@shepai/cli 1.170.0 → 1.171.0-pr527.e2ee839
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apis/json-schema/ActionDispositionEntry.yaml +14 -0
- package/apis/json-schema/DependencyFinding.yaml +28 -0
- package/apis/json-schema/DependencyRiskType.yaml +11 -0
- package/apis/json-schema/DependencyRules.yaml +38 -0
- package/apis/json-schema/EffectivePolicySnapshot.yaml +24 -0
- package/apis/json-schema/ReleaseIntegrityCheck.yaml +22 -0
- package/apis/json-schema/ReleaseIntegrityCheckType.yaml +9 -0
- package/apis/json-schema/ReleaseIntegrityResult.yaml +16 -0
- package/apis/json-schema/ReleaseRules.yaml +21 -0
- package/apis/json-schema/SecurityActionCategory.yaml +10 -0
- package/apis/json-schema/SecurityActionDisposition.yaml +8 -0
- package/apis/json-schema/SecurityConfig.yaml +17 -0
- package/apis/json-schema/SecurityEvent.yaml +36 -0
- package/apis/json-schema/SecurityMode.yaml +8 -0
- package/apis/json-schema/SecurityPolicy.yaml +24 -0
- package/apis/json-schema/SecuritySeverity.yaml +9 -0
- package/apis/json-schema/Settings.yaml +3 -0
- package/dist/packages/core/src/application/ports/output/agents/agent-executor.interface.d.ts +15 -1
- package/dist/packages/core/src/application/ports/output/agents/agent-executor.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +3 -1
- package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/repositories/security-event.repository.interface.d.ts +76 -0
- package/dist/packages/core/src/application/ports/output/repositories/security-event.repository.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/repositories/security-event.repository.interface.js +11 -0
- package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.d.ts +38 -0
- package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.js +9 -0
- package/dist/packages/core/src/application/ports/output/services/security-policy-service.interface.d.ts +77 -0
- package/dist/packages/core/src/application/ports/output/services/security-policy-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/security-policy-service.interface.js +13 -0
- package/dist/packages/core/src/application/ports/output/services/spec-initializer.interface.d.ts +11 -0
- package/dist/packages/core/src/application/ports/output/services/spec-initializer.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/agents/approve-agent-run.use-case.js +2 -0
- package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/agents/reject-agent-run.use-case.js +2 -0
- package/dist/packages/core/src/application/use-cases/features/check-and-unblock-features.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/check-and-unblock-features.use-case.js +2 -0
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +1 -0
- package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +2 -0
- package/dist/packages/core/src/application/use-cases/features/start-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/start-feature.use-case.js +2 -0
- package/dist/packages/core/src/application/use-cases/security/enforce-security.use-case.d.ts +71 -0
- package/dist/packages/core/src/application/use-cases/security/enforce-security.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/security/enforce-security.use-case.js +215 -0
- package/dist/packages/core/src/application/use-cases/security/evaluate-security-policy.use-case.d.ts +24 -0
- package/dist/packages/core/src/application/use-cases/security/evaluate-security-policy.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/security/evaluate-security-policy.use-case.js +56 -0
- package/dist/packages/core/src/application/use-cases/security/get-security-state.use-case.d.ts +36 -0
- package/dist/packages/core/src/application/use-cases/security/get-security-state.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/security/get-security-state.use-case.js +76 -0
- package/dist/packages/core/src/application/use-cases/security/record-security-event.use-case.d.ts +14 -0
- package/dist/packages/core/src/application/use-cases/security/record-security-event.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/security/record-security-event.use-case.js +46 -0
- package/dist/packages/core/src/application/use-cases/upgrade/upgrade-cli.use-case.d.ts +1 -0
- package/dist/packages/core/src/application/use-cases/upgrade/upgrade-cli.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/upgrade/upgrade-cli.use-case.js +59 -2
- package/dist/packages/core/src/domain/errors/security-violation.error.d.ts +15 -0
- package/dist/packages/core/src/domain/errors/security-violation.error.d.ts.map +1 -0
- package/dist/packages/core/src/domain/errors/security-violation.error.js +20 -0
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +5 -1
- package/dist/packages/core/src/domain/generated/output.d.ts +259 -0
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/domain/generated/output.js +43 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +57 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/security-event.mapper.d.ts +44 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/security-event.mapper.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/security-event.mapper.js +55 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +3 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +14 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/053-add-security-settings-columns.d.ts +18 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/053-add-security-settings-columns.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/053-add-security-settings-columns.js +31 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/054-create-security-events-table.d.ts +29 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/054-create-security-events-table.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/054-create-security-events-table.js +53 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-security-event.repository.d.ts +24 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-security-event.repository.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-security-event.repository.js +96 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +12 -3
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts +2 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +12 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/security-constraint-validator.d.ts +22 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/security-constraint-validator.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/security-constraint-validator.js +30 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts +10 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +34 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +3 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +7 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +3 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +32 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +19 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/security-pre-check.d.ts +45 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/security-pre-check.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/security-pre-check.js +70 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +4 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.js +10 -0
- package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts +10 -1
- package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/external/github-repository.service.js +101 -1
- package/dist/packages/core/src/infrastructure/services/security/dependency-risk-evaluator.d.ts +53 -0
- package/dist/packages/core/src/infrastructure/services/security/dependency-risk-evaluator.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/security/dependency-risk-evaluator.js +241 -0
- package/dist/packages/core/src/infrastructure/services/security/release-integrity-evaluator.d.ts +44 -0
- package/dist/packages/core/src/infrastructure/services/security/release-integrity-evaluator.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/security/release-integrity-evaluator.js +194 -0
- package/dist/packages/core/src/infrastructure/services/security/security-policy-file-reader.d.ts +28 -0
- package/dist/packages/core/src/infrastructure/services/security/security-policy-file-reader.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/security/security-policy-file-reader.js +50 -0
- package/dist/packages/core/src/infrastructure/services/security/security-policy-validator.d.ts +26 -0
- package/dist/packages/core/src/infrastructure/services/security/security-policy-validator.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/security/security-policy-validator.js +147 -0
- package/dist/packages/core/src/infrastructure/services/security/security-policy.service.d.ts +44 -0
- package/dist/packages/core/src/infrastructure/services/security/security-policy.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/security/security-policy.service.js +174 -0
- package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.d.ts +1 -0
- package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.js +61 -0
- package/dist/src/presentation/cli/commands/security.command.d.ts +16 -0
- package/dist/src/presentation/cli/commands/security.command.d.ts.map +1 -0
- package/dist/src/presentation/cli/commands/security.command.js +118 -0
- package/dist/src/presentation/cli/commands/upgrade.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/upgrade.command.js +68 -3
- package/dist/src/presentation/cli/index.js +2 -0
- package/dist/src/presentation/web/app/actions/security.d.ts +28 -0
- package/dist/src/presentation/web/app/actions/security.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/security.js +59 -0
- package/dist/src/presentation/web/app/build-graph-nodes.d.ts +3 -1
- package/dist/src/presentation/web/app/build-graph-nodes.d.ts.map +1 -1
- package/dist/src/presentation/web/app/build-graph-nodes.js +2 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +3 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.js +2 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts +3 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.js +3 -2
- package/dist/src/presentation/web/components/common/repository-node/security-panel.d.ts +6 -0
- package/dist/src/presentation/web/components/common/repository-node/security-panel.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/repository-node/security-panel.js +29 -0
- package/dist/src/presentation/web/components/common/repository-node/security-panel.stories.d.ts +10 -0
- package/dist/src/presentation/web/components/common/repository-node/security-panel.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/repository-node/security-panel.stories.js +53 -0
- package/dist/src/presentation/web/components/common/security-badge.d.ts +7 -0
- package/dist/src/presentation/web/components/common/security-badge.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/security-badge.js +30 -0
- package/dist/src/presentation/web/components/common/security-badge.stories.d.ts +12 -0
- package/dist/src/presentation/web/components/common/security-badge.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/security-badge.stories.js +20 -0
- package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-page-client.js +16 -3
- package/dist/src/presentation/web/components/features/settings/supply-chain-security-settings-section.d.ts +6 -0
- package/dist/src/presentation/web/components/features/settings/supply-chain-security-settings-section.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/settings/supply-chain-security-settings-section.js +60 -0
- package/dist/src/presentation/web/components/features/settings/supply-chain-security-settings-section.stories.d.ts +14 -0
- package/dist/src/presentation/web/components/features/settings/supply-chain-security-settings-section.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/settings/supply-chain-security-settings-section.stories.js +116 -0
- package/dist/translations/ar/cli.json +22 -0
- package/dist/translations/ar/web.json +43 -1
- package/dist/translations/de/cli.json +22 -0
- package/dist/translations/de/web.json +43 -1
- package/dist/translations/en/cli.json +22 -0
- package/dist/translations/en/web.json +43 -1
- package/dist/translations/es/cli.json +22 -0
- package/dist/translations/es/web.json +43 -1
- package/dist/translations/fr/cli.json +22 -0
- package/dist/translations/fr/web.json +43 -1
- package/dist/translations/he/cli.json +22 -0
- package/dist/translations/he/web.json +43 -1
- package/dist/translations/pt/cli.json +22 -0
- package/dist/translations/pt/web.json +43 -1
- package/dist/translations/ru/cli.json +22 -0
- package/dist/translations/ru/web.json +43 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +3 -3
- package/web/.next/required-server-files.json +3 -3
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +2 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +2 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js +2 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +2 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +2 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +2 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +2 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/chat/page.js +2 -1
- package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
- package/web/.next/server/app/(dashboard)/create/page.js +2 -1
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +2 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +38 -38
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +2 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/page.js +2 -1
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +2 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +2 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
- package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
- package/web/.next/server/app/api/sessions/route.js.nft.json +1 -1
- package/web/.next/server/app/api/sessions-batch/route.js.nft.json +1 -1
- package/web/.next/server/app/features/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/features/page.js.nft.json +1 -1
- package/web/.next/server/app/features/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +33 -18
- package/web/.next/server/app/settings/page.js +1 -1
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +13 -13
- package/web/.next/server/app/skills/page.js +2 -1
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/tools/page.js +2 -1
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__c78383b1._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__c78383b1._.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_ad0071c9.js +3 -0
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_ad0071c9.js.map +1 -0
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_90d98b2b.js +3 -0
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_90d98b2b.js.map +1 -0
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_d3828105.js +3 -0
- package/web/.next/server/chunks/ssr/744ca_web__next-internal_server_app_(dashboard)_chat_page_actions_d3828105.js.map +1 -0
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__51ec77a8._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__51ec77a8._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__540c615f._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__66047a1b._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__66047a1b._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9a9cb046._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9a9cb046._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a2d6c0ac._.js +4 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a2d6c0ac._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a932cd3a._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__a932cd3a._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aa72e794._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aa72e794._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_02580450._.js +3 -0
- package/web/.next/server/chunks/ssr/_02580450._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
- package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_1594e369._.js +9 -0
- package/web/.next/server/chunks/ssr/_1594e369._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_21d37090._.js +3 -0
- package/web/.next/server/chunks/ssr/_21d37090._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_45496654._.js +1 -1
- package/web/.next/server/chunks/ssr/_45496654._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_4cbb7f95._.js +1 -1
- package/web/.next/server/chunks/ssr/_4cbb7f95._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_5119a3df._.js +1 -1
- package/web/.next/server/chunks/ssr/_5119a3df._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
- package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_0d7dd23b._.js → _767748d2._.js} +2 -2
- package/web/.next/server/chunks/ssr/_767748d2._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_df737cce._.js +1 -1
- package/web/.next/server/chunks/ssr/{_77ae079a._.js → _ee42a212._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_77ae079a._.js.map → _ee42a212._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_f8c55130._.js +4 -0
- package/web/.next/server/chunks/ssr/_f8c55130._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_ff04802c._.js +3 -0
- package/web/.next/server/chunks/ssr/_ff04802c._.js.map +1 -0
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js +1 -1
- package/web/.next/server/chunks/ssr/f3a1f_components_common_control-center-drawer_repository-drawer-client_tsx_39a00c03._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_17d39233._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_17d39233._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_54b02639._.js +5 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_54b02639._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_7b7b9e3b._.js +5 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_7b7b9e3b._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_807cba76._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_807cba76._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_90b5e66e.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_90b5e66e.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_4ce30db7.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_e4032193.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_skills_8a174cac._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_db9fa0c2._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_db9fa0c2._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_e1cd1869._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_e1cd1869._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_e3a30e30._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_e3a30e30._.js.map +1 -0
- package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js +1 -1
- package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js.map +1 -1
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +74 -59
- package/web/.next/static/chunks/051873309d87fb45.css +1 -0
- package/web/.next/static/chunks/{8e12deeabf6624e9.js → 16fa4d3877c28fe2.js} +1 -1
- package/web/.next/static/chunks/23d80bb760e7dc4c.js +1 -0
- package/web/.next/static/chunks/30a0ba9015f94405.js +7 -0
- package/web/.next/static/chunks/{7a6854bb07182777.js → 39f6ad3f9005703a.js} +1 -1
- package/web/.next/static/chunks/3aba9d2242420cb5.js +1 -0
- package/web/.next/static/chunks/7a6f56f37aaa17ea.js +1 -0
- package/web/.next/static/chunks/{b0a6fce5425f8d3a.js → 7e05e7e25220ee9a.js} +1 -1
- package/web/.next/static/chunks/{f9da308b3033c57a.js → 89dd90bf14488ec0.js} +1 -1
- package/web/.next/static/chunks/{2b2f3a70ebd6ac1c.js → 9374d251360e808b.js} +1 -1
- package/web/.next/static/chunks/{f29814a72404ea2b.js → 9423dc2310202fda.js} +1 -1
- package/web/.next/static/chunks/a794cf7a1a5648dd.js +1 -0
- package/web/.next/static/chunks/{3d1df5c349d855eb.js → a8edb9423086e83f.js} +1 -1
- package/web/.next/static/chunks/ae81796726a9bba3.js +1 -0
- package/web/.next/static/chunks/{a3802d6f8677cd04.js → b9c62932ed987239.js} +2 -2
- package/web/.next/static/chunks/{c5a0b452afc8fe47.js → d1c3e0ee8e788c87.js} +1 -1
- package/web/.next/static/chunks/{ca23a8642f750548.js → e8c3c12f92e9a521.js} +2 -2
- package/web/.next/static/chunks/f3d5e0ae13def35a.js +1 -0
- package/web/.next/static/chunks/{d5366257d6b9f855.js → fb8dadb64c0ffc6b.js} +1 -1
- package/web/.next/static/chunks/fd232b88b5b50b2e.js +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__1cd4327c._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4fb81977._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__7dcd0917._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__92ffd5ee._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__92ffd5ee._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b020c17d._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b020c17d._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ba7f5873._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js +0 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c5e09f6f._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fa525872._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fa525872._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_02e01240._.js +0 -4
- package/web/.next/server/chunks/ssr/_02e01240._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_0d7dd23b._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_18886033._.js +0 -4
- package/web/.next/server/chunks/ssr/_18886033._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_22e00a14._.js +0 -4
- package/web/.next/server/chunks/ssr/_22e00a14._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_43ba79e7._.js +0 -3
- package/web/.next/server/chunks/ssr/_43ba79e7._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_a5a5901d._.js +0 -4
- package/web/.next/server/chunks/ssr/_a5a5901d._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_a963dd3c._.js +0 -3
- package/web/.next/server/chunks/ssr/_a963dd3c._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_ad09f271._.js +0 -4
- package/web/.next/server/chunks/ssr/_ad09f271._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_c3f595c6._.js +0 -4
- package/web/.next/server/chunks/ssr/_c3f595c6._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_deabc145._.js +0 -3
- package/web/.next/server/chunks/ssr/_deabc145._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_e3f14907._.js +0 -9
- package/web/.next/server/chunks/ssr/_e3f14907._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_ea9e1556._.js +0 -4
- package/web/.next/server/chunks/ssr/_ea9e1556._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_f1ba9be6._.js +0 -6
- package/web/.next/server/chunks/ssr/_f1ba9be6._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_f33cd07e._.js +0 -6
- package/web/.next/server/chunks/ssr/_f33cd07e._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_f8b45233._.js +0 -4
- package/web/.next/server/chunks/ssr/_f8b45233._.js.map +0 -1
- package/web/.next/static/chunks/06a86173379e6c51.js +0 -1
- package/web/.next/static/chunks/16ed73f9880b7d63.js +0 -1
- package/web/.next/static/chunks/4559a403ee40dd19.js +0 -7
- package/web/.next/static/chunks/74e5b5c7950efbc1.js +0 -1
- package/web/.next/static/chunks/8b0a9cb5109fe899.js +0 -1
- package/web/.next/static/chunks/9c6f8f49799efd3a.js +0 -1
- package/web/.next/static/chunks/b14085e99b88e7f7.css +0 -1
- package/web/.next/static/chunks/b65e555419a0c664.js +0 -1
- package/web/.next/static/chunks/f51250616da82bd2.js +0 -1
- /package/web/.next/static/{0KDwNT3AGQmFGIwjHx99r → t6SUt71jyk_PYf152Imog}/_buildManifest.js +0 -0
- /package/web/.next/static/{0KDwNT3AGQmFGIwjHx99r → t6SUt71jyk_PYf152Imog}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{0KDwNT3AGQmFGIwjHx99r → t6SUt71jyk_PYf152Imog}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Policy Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates a parsed security policy object against the expected schema.
|
|
5
|
+
* Checks required fields, valid enum values, contradictory rules,
|
|
6
|
+
* and reasonable input limits. Returns structured validation results
|
|
7
|
+
* with per-field error messages.
|
|
8
|
+
*/
|
|
9
|
+
import { SecurityMode, SecurityActionCategory, SecurityActionDisposition, } from '../../../domain/generated/output.js';
|
|
10
|
+
/** Maximum number of action disposition entries allowed */
|
|
11
|
+
const MAX_ACTION_DISPOSITIONS = 100;
|
|
12
|
+
/** Maximum number of entries in allowlist or denylist */
|
|
13
|
+
const MAX_LIST_ENTRIES = 100;
|
|
14
|
+
const VALID_MODES = Object.values(SecurityMode);
|
|
15
|
+
const VALID_CATEGORIES = Object.values(SecurityActionCategory);
|
|
16
|
+
const VALID_DISPOSITIONS = Object.values(SecurityActionDisposition);
|
|
17
|
+
/**
|
|
18
|
+
* Validates parsed security policy objects against the expected schema.
|
|
19
|
+
*/
|
|
20
|
+
export class SecurityPolicyValidator {
|
|
21
|
+
/**
|
|
22
|
+
* Validate a parsed policy object.
|
|
23
|
+
*
|
|
24
|
+
* @param policy - The parsed policy object (from YAML)
|
|
25
|
+
* @returns Validation result with errors array
|
|
26
|
+
*/
|
|
27
|
+
validate(policy) {
|
|
28
|
+
const errors = [];
|
|
29
|
+
// Validate mode (optional, but if present must be valid)
|
|
30
|
+
if (policy.mode !== undefined) {
|
|
31
|
+
if (!VALID_MODES.includes(policy.mode)) {
|
|
32
|
+
errors.push(`Invalid mode: "${String(policy.mode)}". Valid values: ${VALID_MODES.join(', ')}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Validate actionDispositions (optional, but if present must be valid)
|
|
36
|
+
if (policy.actionDispositions !== undefined) {
|
|
37
|
+
this.validateActionDispositions(policy.actionDispositions, errors);
|
|
38
|
+
}
|
|
39
|
+
// Validate dependencyRules (optional, but if present must be valid)
|
|
40
|
+
if (policy.dependencyRules !== undefined) {
|
|
41
|
+
this.validateDependencyRules(policy.dependencyRules, errors);
|
|
42
|
+
}
|
|
43
|
+
// Validate releaseRules (optional, but if present must be valid)
|
|
44
|
+
if (policy.releaseRules !== undefined) {
|
|
45
|
+
this.validateReleaseRules(policy.releaseRules, errors);
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
valid: errors.length === 0,
|
|
49
|
+
errors,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
validateActionDispositions(value, errors) {
|
|
53
|
+
if (!Array.isArray(value)) {
|
|
54
|
+
errors.push('actionDispositions must be an array');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (value.length > MAX_ACTION_DISPOSITIONS) {
|
|
58
|
+
errors.push(`actionDispositions exceeds limit: ${value.length} entries (max ${MAX_ACTION_DISPOSITIONS})`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Track categories to detect contradictions
|
|
62
|
+
const categoryToDisposition = new Map();
|
|
63
|
+
for (let i = 0; i < value.length; i++) {
|
|
64
|
+
const entry = value[i];
|
|
65
|
+
if (!entry || typeof entry !== 'object') {
|
|
66
|
+
errors.push(`actionDispositions[${i}] must be an object`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const category = entry.category;
|
|
70
|
+
const disposition = entry.disposition;
|
|
71
|
+
if (!VALID_CATEGORIES.includes(category)) {
|
|
72
|
+
errors.push(`actionDispositions[${i}].category: invalid value "${String(category)}". Valid values: ${VALID_CATEGORIES.join(', ')}`);
|
|
73
|
+
}
|
|
74
|
+
if (!VALID_DISPOSITIONS.includes(disposition)) {
|
|
75
|
+
errors.push(`actionDispositions[${i}].disposition: invalid value "${String(disposition)}". Valid values: ${VALID_DISPOSITIONS.join(', ')}`);
|
|
76
|
+
}
|
|
77
|
+
// Check for contradictory entries (same category, different disposition)
|
|
78
|
+
if (VALID_CATEGORIES.includes(category) &&
|
|
79
|
+
VALID_DISPOSITIONS.includes(disposition)) {
|
|
80
|
+
const existing = categoryToDisposition.get(category);
|
|
81
|
+
if (existing !== undefined && existing !== disposition) {
|
|
82
|
+
errors.push(`Contradictory action dispositions for category "${category}": "${existing}" vs "${disposition}"`);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
categoryToDisposition.set(category, disposition);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
validateDependencyRules(value, errors) {
|
|
91
|
+
if (!value || typeof value !== 'object') {
|
|
92
|
+
errors.push('dependencyRules must be an object');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const rules = value;
|
|
96
|
+
// Validate boolean fields
|
|
97
|
+
const booleanFields = [
|
|
98
|
+
'checkLockfileConsistency',
|
|
99
|
+
'checkLifecycleScripts',
|
|
100
|
+
'checkNonRegistrySource',
|
|
101
|
+
'enforceStrictVersionRanges',
|
|
102
|
+
];
|
|
103
|
+
for (const field of booleanFields) {
|
|
104
|
+
if (rules[field] !== undefined && typeof rules[field] !== 'boolean') {
|
|
105
|
+
errors.push(`dependencyRules.${field} must be a boolean, got ${typeof rules[field]}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Validate list fields
|
|
109
|
+
if (rules.allowlist !== undefined) {
|
|
110
|
+
this.validateStringList('dependencyRules.allowlist', rules.allowlist, errors);
|
|
111
|
+
}
|
|
112
|
+
if (rules.denylist !== undefined) {
|
|
113
|
+
this.validateStringList('dependencyRules.denylist', rules.denylist, errors);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
validateReleaseRules(value, errors) {
|
|
117
|
+
if (!value || typeof value !== 'object') {
|
|
118
|
+
errors.push('releaseRules must be an object');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const rules = value;
|
|
122
|
+
const booleanFields = [
|
|
123
|
+
'requireCiOnlyPublishing',
|
|
124
|
+
'requireProvenance',
|
|
125
|
+
'checkWorkflowIntegrity',
|
|
126
|
+
];
|
|
127
|
+
for (const field of booleanFields) {
|
|
128
|
+
if (rules[field] !== undefined && typeof rules[field] !== 'boolean') {
|
|
129
|
+
errors.push(`releaseRules.${field} must be a boolean, got ${typeof rules[field]}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
validateStringList(path, value, errors) {
|
|
134
|
+
if (!Array.isArray(value)) {
|
|
135
|
+
errors.push(`${path} must be an array`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (value.length > MAX_LIST_ENTRIES) {
|
|
139
|
+
errors.push(`${path} exceeds limit: ${value.length} entries (max ${MAX_LIST_ENTRIES})`);
|
|
140
|
+
}
|
|
141
|
+
for (let i = 0; i < value.length; i++) {
|
|
142
|
+
if (typeof value[i] !== 'string') {
|
|
143
|
+
errors.push(`${path}[${i}] must be a string`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Policy Service
|
|
3
|
+
*
|
|
4
|
+
* Central policy engine implementing ISecurityPolicyService.
|
|
5
|
+
* Reads the policy file, validates it, merges with persisted settings defaults
|
|
6
|
+
* using deterministic precedence, and returns an EffectivePolicySnapshot.
|
|
7
|
+
*
|
|
8
|
+
* Precedence: global settings defaults < repository policy file (stricter wins).
|
|
9
|
+
* A lower-precedence layer cannot weaken a stricter higher-precedence rule.
|
|
10
|
+
*/
|
|
11
|
+
import { SecurityActionCategory, SecurityActionDisposition } from '../../../domain/generated/output.js';
|
|
12
|
+
import type { EffectivePolicySnapshot } from '../../../domain/generated/output.js';
|
|
13
|
+
import type { ISecurityPolicyService, PolicyValidationResult } from '../../../application/ports/output/services/security-policy-service.interface.js';
|
|
14
|
+
import type { ISettingsRepository } from '../../../application/ports/output/repositories/settings.repository.interface.js';
|
|
15
|
+
import { SecurityPolicyFileReader } from './security-policy-file-reader.js';
|
|
16
|
+
import { SecurityPolicyValidator } from './security-policy-validator.js';
|
|
17
|
+
export declare class SecurityPolicyService implements ISecurityPolicyService {
|
|
18
|
+
private readonly fileReader;
|
|
19
|
+
private readonly validator;
|
|
20
|
+
private readonly settingsRepo;
|
|
21
|
+
private readonly cache;
|
|
22
|
+
constructor(fileReader: SecurityPolicyFileReader, validator: SecurityPolicyValidator, settingsRepo: ISettingsRepository);
|
|
23
|
+
evaluatePolicy(repositoryPath: string): Promise<EffectivePolicySnapshot>;
|
|
24
|
+
getEffectivePolicy(repositoryPath: string): Promise<EffectivePolicySnapshot>;
|
|
25
|
+
validatePolicyFile(filePath: string): Promise<PolicyValidationResult>;
|
|
26
|
+
getActionDisposition(policy: EffectivePolicySnapshot, actionCategory: SecurityActionCategory): SecurityActionDisposition;
|
|
27
|
+
/**
|
|
28
|
+
* Build a default snapshot from settings mode only (no policy file).
|
|
29
|
+
*/
|
|
30
|
+
private buildDefaultSnapshot;
|
|
31
|
+
/**
|
|
32
|
+
* Merge settings defaults with policy file, applying strict-wins precedence.
|
|
33
|
+
*/
|
|
34
|
+
private mergePolicy;
|
|
35
|
+
/**
|
|
36
|
+
* Return the stricter of two SecurityMode values.
|
|
37
|
+
*/
|
|
38
|
+
private stricterMode;
|
|
39
|
+
/**
|
|
40
|
+
* Return the stricter of two SecurityActionDisposition values.
|
|
41
|
+
*/
|
|
42
|
+
private stricterDisposition;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=security-policy.service.d.ts.map
|
package/dist/packages/core/src/infrastructure/services/security/security-policy.service.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-policy.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/security/security-policy.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAEL,sBAAsB,EACtB,yBAAyB,EAC1B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EACV,uBAAuB,EAGxB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,iFAAiF,CAAC;AACzF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iFAAiF,CAAC;AAC3H,OAAO,EACL,wBAAwB,EAEzB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AA4BzE,qBACa,qBAAsB,YAAW,sBAAsB;IAKhE,OAAO,CAAC,QAAQ,CAAC,UAAU;IAE3B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAR/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8C;gBAIjD,UAAU,EAAE,wBAAwB,EAEpC,SAAS,EAAE,uBAAuB,EAElC,YAAY,EAAE,mBAAmB;IAG9C,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IA6BxE,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAQ5E,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAY3E,oBAAoB,CAClB,MAAM,EAAE,uBAAuB,EAC/B,cAAc,EAAE,sBAAsB,GACrC,yBAAyB;IAK5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;OAEG;IACH,OAAO,CAAC,WAAW;IAuCnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAMpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAQ5B"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Policy Service
|
|
3
|
+
*
|
|
4
|
+
* Central policy engine implementing ISecurityPolicyService.
|
|
5
|
+
* Reads the policy file, validates it, merges with persisted settings defaults
|
|
6
|
+
* using deterministic precedence, and returns an EffectivePolicySnapshot.
|
|
7
|
+
*
|
|
8
|
+
* Precedence: global settings defaults < repository policy file (stricter wins).
|
|
9
|
+
* A lower-precedence layer cannot weaken a stricter higher-precedence rule.
|
|
10
|
+
*/
|
|
11
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
12
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
13
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
14
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
15
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
16
|
+
};
|
|
17
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
18
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
19
|
+
};
|
|
20
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
21
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
22
|
+
};
|
|
23
|
+
import { injectable, inject } from 'tsyringe';
|
|
24
|
+
import { SecurityMode, SecurityActionCategory, SecurityActionDisposition, } from '../../../domain/generated/output.js';
|
|
25
|
+
import { SecurityPolicyFileReader, SECURITY_POLICY_FILENAME, } from './security-policy-file-reader.js';
|
|
26
|
+
import { SecurityPolicyValidator } from './security-policy-validator.js';
|
|
27
|
+
import { dirname } from 'node:path';
|
|
28
|
+
/**
|
|
29
|
+
* Numeric rank for comparing SecurityMode strictness.
|
|
30
|
+
* Higher number = stricter mode.
|
|
31
|
+
*/
|
|
32
|
+
const MODE_STRICTNESS = {
|
|
33
|
+
[SecurityMode.Disabled]: 0,
|
|
34
|
+
[SecurityMode.Advisory]: 1,
|
|
35
|
+
[SecurityMode.Enforce]: 2,
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Numeric rank for comparing disposition strictness.
|
|
39
|
+
* Higher number = more restrictive.
|
|
40
|
+
*/
|
|
41
|
+
const DISPOSITION_STRICTNESS = {
|
|
42
|
+
[SecurityActionDisposition.Allowed]: 0,
|
|
43
|
+
[SecurityActionDisposition.ApprovalRequired]: 1,
|
|
44
|
+
[SecurityActionDisposition.Denied]: 2,
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* All action categories for building default dispositions.
|
|
48
|
+
*/
|
|
49
|
+
const ALL_CATEGORIES = Object.values(SecurityActionCategory);
|
|
50
|
+
let SecurityPolicyService = class SecurityPolicyService {
|
|
51
|
+
fileReader;
|
|
52
|
+
validator;
|
|
53
|
+
settingsRepo;
|
|
54
|
+
cache = new Map();
|
|
55
|
+
constructor(fileReader, validator, settingsRepo) {
|
|
56
|
+
this.fileReader = fileReader;
|
|
57
|
+
this.validator = validator;
|
|
58
|
+
this.settingsRepo = settingsRepo;
|
|
59
|
+
}
|
|
60
|
+
async evaluatePolicy(repositoryPath) {
|
|
61
|
+
// Load settings defaults
|
|
62
|
+
const settings = await this.settingsRepo.load();
|
|
63
|
+
const settingsMode = settings?.security?.mode ?? SecurityMode.Advisory;
|
|
64
|
+
// Read policy file
|
|
65
|
+
const policyFile = await this.fileReader.read(repositoryPath);
|
|
66
|
+
if (!policyFile) {
|
|
67
|
+
// No policy file — use settings defaults
|
|
68
|
+
const snapshot = this.buildDefaultSnapshot(settingsMode);
|
|
69
|
+
this.cache.set(repositoryPath, snapshot);
|
|
70
|
+
return snapshot;
|
|
71
|
+
}
|
|
72
|
+
// Validate policy file
|
|
73
|
+
const validation = this.validator.validate(policyFile);
|
|
74
|
+
if (!validation.valid) {
|
|
75
|
+
throw new Error(`Security policy validation failed for ${repositoryPath}:\n${validation.errors.join('\n')}`);
|
|
76
|
+
}
|
|
77
|
+
// Merge with precedence: settings defaults < policy file (stricter wins)
|
|
78
|
+
const snapshot = this.mergePolicy(settingsMode, policyFile);
|
|
79
|
+
this.cache.set(repositoryPath, snapshot);
|
|
80
|
+
return snapshot;
|
|
81
|
+
}
|
|
82
|
+
async getEffectivePolicy(repositoryPath) {
|
|
83
|
+
const cached = this.cache.get(repositoryPath);
|
|
84
|
+
if (cached) {
|
|
85
|
+
return cached;
|
|
86
|
+
}
|
|
87
|
+
return this.evaluatePolicy(repositoryPath);
|
|
88
|
+
}
|
|
89
|
+
async validatePolicyFile(filePath) {
|
|
90
|
+
// Read the file from the directory containing it
|
|
91
|
+
const dirPath = dirname(filePath);
|
|
92
|
+
const policyFile = await this.fileReader.read(dirPath);
|
|
93
|
+
if (!policyFile) {
|
|
94
|
+
return { valid: true, errors: [] };
|
|
95
|
+
}
|
|
96
|
+
return this.validator.validate(policyFile);
|
|
97
|
+
}
|
|
98
|
+
getActionDisposition(policy, actionCategory) {
|
|
99
|
+
const entry = policy.actionDispositions.find((d) => d.category === actionCategory);
|
|
100
|
+
return entry?.disposition ?? SecurityActionDisposition.Allowed;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Build a default snapshot from settings mode only (no policy file).
|
|
104
|
+
*/
|
|
105
|
+
buildDefaultSnapshot(mode) {
|
|
106
|
+
return {
|
|
107
|
+
mode,
|
|
108
|
+
source: 'settings-default',
|
|
109
|
+
evaluatedAt: new Date().toISOString(),
|
|
110
|
+
actionDispositions: ALL_CATEGORIES.map((category) => ({
|
|
111
|
+
category,
|
|
112
|
+
disposition: SecurityActionDisposition.Allowed,
|
|
113
|
+
})),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Merge settings defaults with policy file, applying strict-wins precedence.
|
|
118
|
+
*/
|
|
119
|
+
mergePolicy(settingsMode, policyFile) {
|
|
120
|
+
// Mode: stricter wins
|
|
121
|
+
const fileMode = policyFile.mode ?? SecurityMode.Advisory;
|
|
122
|
+
const effectiveMode = this.stricterMode(settingsMode, fileMode);
|
|
123
|
+
// Action dispositions: merge file entries with defaults, stricter wins
|
|
124
|
+
const dispositionMap = new Map();
|
|
125
|
+
// Start with defaults (all Allowed)
|
|
126
|
+
for (const category of ALL_CATEGORIES) {
|
|
127
|
+
dispositionMap.set(category, SecurityActionDisposition.Allowed);
|
|
128
|
+
}
|
|
129
|
+
// Apply policy file entries (can only make stricter, not weaker)
|
|
130
|
+
if (policyFile.actionDispositions) {
|
|
131
|
+
for (const entry of policyFile.actionDispositions) {
|
|
132
|
+
const current = dispositionMap.get(entry.category);
|
|
133
|
+
if (current !== undefined) {
|
|
134
|
+
dispositionMap.set(entry.category, this.stricterDisposition(current, entry.disposition));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const actionDispositions = [];
|
|
139
|
+
for (const [category, disposition] of dispositionMap) {
|
|
140
|
+
actionDispositions.push({ category, disposition });
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
mode: effectiveMode,
|
|
144
|
+
source: SECURITY_POLICY_FILENAME,
|
|
145
|
+
evaluatedAt: new Date().toISOString(),
|
|
146
|
+
actionDispositions,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Return the stricter of two SecurityMode values.
|
|
151
|
+
*/
|
|
152
|
+
stricterMode(a, b) {
|
|
153
|
+
const rankA = MODE_STRICTNESS[a] ?? 0;
|
|
154
|
+
const rankB = MODE_STRICTNESS[b] ?? 0;
|
|
155
|
+
return rankA >= rankB ? a : b;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Return the stricter of two SecurityActionDisposition values.
|
|
159
|
+
*/
|
|
160
|
+
stricterDisposition(a, b) {
|
|
161
|
+
const rankA = DISPOSITION_STRICTNESS[a] ?? 0;
|
|
162
|
+
const rankB = DISPOSITION_STRICTNESS[b] ?? 0;
|
|
163
|
+
return rankA >= rankB ? a : b;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
SecurityPolicyService = __decorate([
|
|
167
|
+
injectable(),
|
|
168
|
+
__param(0, inject('SecurityPolicyFileReader')),
|
|
169
|
+
__param(1, inject('SecurityPolicyValidator')),
|
|
170
|
+
__param(2, inject('ISettingsRepository')),
|
|
171
|
+
__metadata("design:paramtypes", [SecurityPolicyFileReader,
|
|
172
|
+
SecurityPolicyValidator, Object])
|
|
173
|
+
], SecurityPolicyService);
|
|
174
|
+
export { SecurityPolicyService };
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import type { ISpecInitializerService, SpecInitializerResult } from '../../../application/ports/output/services/spec-initializer.interface.js';
|
|
9
9
|
export declare class SpecInitializerService implements ISpecInitializerService {
|
|
10
10
|
initialize(basePath: string, slug: string, featureNumber: number, description: string, mode?: 'fast'): Promise<SpecInitializerResult>;
|
|
11
|
+
scaffoldSecurityPolicy(repositoryPath: string): Promise<string>;
|
|
11
12
|
/**
|
|
12
13
|
* Scan specs/ for existing NNN-* directories and return the next available number.
|
|
13
14
|
* Uses the DB-derived hint as a minimum, but always respects filesystem state.
|
package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-initializer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/spec/spec-initializer.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,mEAAmE,CAAC;
|
|
1
|
+
{"version":3,"file":"spec-initializer.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/spec/spec-initializer.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,mEAAmE,CAAC;AAwT3E,qBAAa,sBAAuB,YAAW,uBAAuB;IAC9D,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,qBAAqB,CAAC;IAqC3B,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMrE;;;OAGG;YACW,iBAAiB;CAoBhC"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { mkdir, readdir, writeFile } from 'node:fs/promises';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
|
+
import { SECURITY_POLICY_FILENAME } from '../../services/security/security-policy-file-reader.js';
|
|
10
11
|
/**
|
|
11
12
|
* Pad a number to 3 digits with leading zeros.
|
|
12
13
|
*/
|
|
@@ -239,6 +240,61 @@ const TEMPLATES = [
|
|
|
239
240
|
{ filename: 'tasks.yaml', content: TASKS_YAML },
|
|
240
241
|
{ filename: 'feature.yaml', content: FEATURE_YAML },
|
|
241
242
|
];
|
|
243
|
+
// ─── Security Policy Template ─────────────────────────────────────
|
|
244
|
+
// Baseline shep.security.yaml for new repositories.
|
|
245
|
+
const SECURITY_POLICY_YAML = `# Shep Supply Chain Security Policy
|
|
246
|
+
# This file defines the security posture for this repository.
|
|
247
|
+
# Shep evaluates this policy during agent execution and CI enforcement.
|
|
248
|
+
#
|
|
249
|
+
# Docs: https://shep.bot/docs/security/policy
|
|
250
|
+
|
|
251
|
+
# Security mode controls enforcement behavior:
|
|
252
|
+
# Disabled - Security checks are skipped entirely
|
|
253
|
+
# Advisory - Checks run and findings are reported, but nothing is blocked
|
|
254
|
+
# Enforce - Checks run and violations block agent actions and CI jobs
|
|
255
|
+
mode: Advisory
|
|
256
|
+
|
|
257
|
+
# Action dispositions control how the agent handles each action category.
|
|
258
|
+
# Each entry maps a category to a disposition:
|
|
259
|
+
# Allowed - Action proceeds without interruption
|
|
260
|
+
# Denied - Action is blocked before execution
|
|
261
|
+
# ApprovalRequired - Action pauses for human approval via HITL gate
|
|
262
|
+
actionDispositions:
|
|
263
|
+
- category: DependencyInstall
|
|
264
|
+
disposition: ApprovalRequired
|
|
265
|
+
- category: PackageScriptExec
|
|
266
|
+
disposition: ApprovalRequired
|
|
267
|
+
- category: CiWorkflowModify
|
|
268
|
+
disposition: ApprovalRequired
|
|
269
|
+
- category: PublishRelease
|
|
270
|
+
disposition: Denied
|
|
271
|
+
- category: SandboxEscalation
|
|
272
|
+
disposition: Denied
|
|
273
|
+
|
|
274
|
+
# Dependency risk rules evaluated by "shep security enforce"
|
|
275
|
+
dependencyRules:
|
|
276
|
+
# Verify lockfile matches package.json (detects phantom dependencies)
|
|
277
|
+
checkLockfileConsistency: true
|
|
278
|
+
# Flag packages with risky lifecycle scripts (preinstall, postinstall)
|
|
279
|
+
checkLifecycleScripts: true
|
|
280
|
+
# Flag dependencies sourced from git, file, or HTTP instead of registry
|
|
281
|
+
checkNonRegistrySource: true
|
|
282
|
+
# Require exact versions (no ^, ~, *, >= ranges)
|
|
283
|
+
enforceStrictVersionRanges: false
|
|
284
|
+
# Packages explicitly allowed (empty = allow all registry packages)
|
|
285
|
+
allowlist: []
|
|
286
|
+
# Packages explicitly blocked (takes precedence over allowlist)
|
|
287
|
+
denylist: []
|
|
288
|
+
|
|
289
|
+
# Release integrity rules for publish-path enforcement
|
|
290
|
+
releaseRules:
|
|
291
|
+
# Require publishing only from CI (not local machines)
|
|
292
|
+
requireCiOnlyPublishing: true
|
|
293
|
+
# Require npm provenance attestation on published packages
|
|
294
|
+
requireProvenance: true
|
|
295
|
+
# Check that release workflow has not been tampered with
|
|
296
|
+
checkWorkflowIntegrity: true
|
|
297
|
+
`;
|
|
242
298
|
export class SpecInitializerService {
|
|
243
299
|
async initialize(basePath, slug, featureNumber, description, mode) {
|
|
244
300
|
// Scan existing specs/ directory for highest NNN prefix to avoid collisions
|
|
@@ -262,6 +318,11 @@ export class SpecInitializerService {
|
|
|
262
318
|
await Promise.all(templates.map(({ filename, content }) => writeFile(join(specDir, filename), applyTemplate(content, vars), 'utf-8')));
|
|
263
319
|
return { specDir, featureNumber: nnn };
|
|
264
320
|
}
|
|
321
|
+
async scaffoldSecurityPolicy(repositoryPath) {
|
|
322
|
+
const filePath = join(repositoryPath, SECURITY_POLICY_FILENAME);
|
|
323
|
+
await writeFile(filePath, SECURITY_POLICY_YAML, 'utf-8');
|
|
324
|
+
return filePath;
|
|
325
|
+
}
|
|
265
326
|
/**
|
|
266
327
|
* Scan specs/ for existing NNN-* directories and return the next available number.
|
|
267
328
|
* Uses the DB-derived hint as a minimum, but always respects filesystem state.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Command Group
|
|
3
|
+
*
|
|
4
|
+
* Top-level security command with subcommands for supply-chain security
|
|
5
|
+
* policy management and enforcement.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* shep security enforce Evaluate and enforce security posture
|
|
9
|
+
* shep security enforce --output json Machine-readable output for CI
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
/**
|
|
13
|
+
* Create the security command group with all subcommands.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createSecurityCommand(): Command;
|
|
16
|
+
//# sourceMappingURL=security.command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/security.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAqH/C"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Command Group
|
|
3
|
+
*
|
|
4
|
+
* Top-level security command with subcommands for supply-chain security
|
|
5
|
+
* policy management and enforcement.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* shep security enforce Evaluate and enforce security posture
|
|
9
|
+
* shep security enforce --output json Machine-readable output for CI
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
import { container } from '../../../../packages/core/src/infrastructure/di/container.js';
|
|
13
|
+
import { EnforceSecurityUseCase } from '../../../../packages/core/src/application/use-cases/security/enforce-security.use-case.js';
|
|
14
|
+
import { SecurityMode } from '../../../../packages/core/src/domain/generated/output.js';
|
|
15
|
+
import { colors, fmt, messages } from '../ui/index.js';
|
|
16
|
+
import { OutputFormatter } from '../ui/output.js';
|
|
17
|
+
import { getCliI18n } from '../i18n.js';
|
|
18
|
+
/**
|
|
19
|
+
* Create the security command group with all subcommands.
|
|
20
|
+
*/
|
|
21
|
+
export function createSecurityCommand() {
|
|
22
|
+
const t = getCliI18n().t;
|
|
23
|
+
const security = new Command('security').description(t('cli:commands.security.description'));
|
|
24
|
+
security
|
|
25
|
+
.command('enforce')
|
|
26
|
+
.description(t('cli:commands.security.enforce.description'))
|
|
27
|
+
.option('-r, --repo <path>', t('cli:commands.security.enforce.repoOption'), process.cwd())
|
|
28
|
+
.option('-o, --output <format>', t('cli:commands.security.enforce.outputOption'), 'table')
|
|
29
|
+
.action(async (options) => {
|
|
30
|
+
try {
|
|
31
|
+
const useCase = container.resolve(EnforceSecurityUseCase);
|
|
32
|
+
const result = await useCase.execute({ repositoryPath: options.repo });
|
|
33
|
+
const outputFormat = options.output;
|
|
34
|
+
if (outputFormat === 'json' || outputFormat === 'yaml') {
|
|
35
|
+
// Machine-readable output
|
|
36
|
+
console.log(OutputFormatter.format(result, outputFormat));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Human-readable table output
|
|
40
|
+
messages.newline();
|
|
41
|
+
if (result.mode === SecurityMode.Disabled) {
|
|
42
|
+
messages.info(t('cli:commands.security.enforce.disabledNote'));
|
|
43
|
+
messages.newline();
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Summary header
|
|
47
|
+
console.log(`${fmt.label(t('cli:commands.security.enforce.modeLabel'))}: ${result.mode}`);
|
|
48
|
+
console.log(`${fmt.label(t('cli:commands.security.enforce.sourceLabel'))}: ${result.policy.source}`);
|
|
49
|
+
console.log(`${fmt.label(t('cli:commands.security.enforce.totalFindingsLabel'))}: ${result.totalFindings}`);
|
|
50
|
+
messages.newline();
|
|
51
|
+
// Dependency findings
|
|
52
|
+
if (result.dependencyFindings.length > 0) {
|
|
53
|
+
console.log(fmt.heading(t('cli:commands.security.enforce.dependencyFindingsLabel')));
|
|
54
|
+
for (const finding of result.dependencyFindings) {
|
|
55
|
+
const severityColor = finding.severity === 'Critical' || finding.severity === 'High'
|
|
56
|
+
? colors.error
|
|
57
|
+
: colors.warning;
|
|
58
|
+
console.log(` ${severityColor(`[${finding.severity}]`)} ${finding.packageName}: ${finding.message}`);
|
|
59
|
+
if (finding.remediation) {
|
|
60
|
+
console.log(` ${colors.muted(finding.remediation)}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
messages.newline();
|
|
64
|
+
}
|
|
65
|
+
// Release integrity
|
|
66
|
+
const failedChecks = result.releaseIntegrity.checks.filter((c) => !c.passed);
|
|
67
|
+
if (failedChecks.length > 0) {
|
|
68
|
+
console.log(fmt.heading(t('cli:commands.security.enforce.releaseIntegrityLabel')));
|
|
69
|
+
for (const check of failedChecks) {
|
|
70
|
+
const severityColor = check.severity === 'Critical' || check.severity === 'High'
|
|
71
|
+
? colors.error
|
|
72
|
+
: colors.warning;
|
|
73
|
+
console.log(` ${severityColor(`[${check.severity}]`)} ${check.message}`);
|
|
74
|
+
}
|
|
75
|
+
messages.newline();
|
|
76
|
+
}
|
|
77
|
+
// Governance findings (audit-only)
|
|
78
|
+
if (result.governanceFindings.length > 0) {
|
|
79
|
+
console.log(fmt.heading(t('cli:commands.security.enforce.governanceFindingsLabel')));
|
|
80
|
+
for (const finding of result.governanceFindings) {
|
|
81
|
+
const severityColor = finding.severity === 'Critical' || finding.severity === 'High'
|
|
82
|
+
? colors.error
|
|
83
|
+
: colors.warning;
|
|
84
|
+
console.log(` ${severityColor(`[${finding.severity}]`)} ${finding.message}`);
|
|
85
|
+
if (finding.remediation) {
|
|
86
|
+
console.log(` ${colors.muted(finding.remediation)}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
messages.newline();
|
|
90
|
+
}
|
|
91
|
+
// Result
|
|
92
|
+
if (result.totalFindings === 0) {
|
|
93
|
+
messages.info(t('cli:commands.security.enforce.noFindings'));
|
|
94
|
+
}
|
|
95
|
+
if (result.passed) {
|
|
96
|
+
messages.success(t('cli:commands.security.enforce.passed'));
|
|
97
|
+
if (result.mode === SecurityMode.Advisory && result.totalFindings > 0) {
|
|
98
|
+
messages.info(t('cli:commands.security.enforce.advisoryNote'));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
messages.error(t('cli:commands.security.enforce.failed'));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
messages.newline();
|
|
106
|
+
}
|
|
107
|
+
if (!result.passed) {
|
|
108
|
+
process.exitCode = 1;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
113
|
+
messages.error(t('cli:commands.security.enforce.failedToEnforce'), err);
|
|
114
|
+
process.exitCode = 1;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
return security;
|
|
118
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/upgrade.command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,IAAI,YAAY,EAAqB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"upgrade.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/upgrade.command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,IAAI,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAY9E,KAAK,OAAO,GAAG,OAAO,YAAY,CAAC;AA8InC;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,OAAsB,GAAG,OAAO,CA6E7E"}
|