@macedon-technologies/batman 1.17.2 → 1.18.0

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.
Files changed (50) hide show
  1. package/.jsii +205 -26
  2. package/.swamp.yaml +6 -0
  3. package/API.md +164 -1
  4. package/CLAUDE.md +44 -0
  5. package/architecture-rules/README.md +42 -0
  6. package/architecture-rules/check.ts +162 -0
  7. package/architecture-rules/rules.json +3 -0
  8. package/architecture-rules/tsconfig.json +14 -0
  9. package/attestation/manifest.ts +40 -0
  10. package/attestation/tsconfig.json +13 -0
  11. package/attestation/verify.ts +142 -0
  12. package/build-tools/scan-generated-workflows.ts +18 -11
  13. package/lib/Application.js +6 -1
  14. package/lib/BatmanProject.js +8 -2
  15. package/lib/BootcampProject.js +8 -2
  16. package/lib/CodeOwnersFile.js +1 -1
  17. package/lib/ProductionDeployWorkflow.js +1 -1
  18. package/lib/ProjenWorkflowHardening.d.ts +18 -0
  19. package/lib/ProjenWorkflowHardening.js +59 -0
  20. package/lib/SoftwareFactoryArchitectureRules.d.ts +10 -0
  21. package/lib/SoftwareFactoryArchitectureRules.js +245 -0
  22. package/lib/SoftwareFactoryAttestation.d.ts +18 -0
  23. package/lib/SoftwareFactoryAttestation.js +221 -0
  24. package/lib/SoftwareFactoryFiles.d.ts +45 -0
  25. package/lib/SoftwareFactoryFiles.js +102 -0
  26. package/lib/SoftwareFactoryModels.d.ts +25 -0
  27. package/lib/SoftwareFactoryModels.js +306 -0
  28. package/lib/SoftwareFactoryOpenSpecGates.d.ts +8 -0
  29. package/lib/SoftwareFactoryOpenSpecGates.js +75 -0
  30. package/lib/SoftwareFactoryWorkflows.d.ts +28 -0
  31. package/lib/SoftwareFactoryWorkflows.js +326 -0
  32. package/lib/StagingDeployWorkflow.js +1 -1
  33. package/lib/WorkflowActionVersions.d.ts +31 -1
  34. package/lib/WorkflowActionVersions.js +5 -1
  35. package/lib/WorkflowAutoDiscover.js +1 -1
  36. package/lib/index.d.ts +1 -0
  37. package/lib/index.js +2 -1
  38. package/lib/utils.js +29 -1
  39. package/models/@goodcraft/github/platform-common-pr.yaml +10 -0
  40. package/models/@swamp/software-factory/platform-common-factory.yaml +240 -0
  41. package/models/@webframp/github/platform-common-issues.yaml +8 -0
  42. package/models/command/shell/platform-common-shell-architecture.yaml +8 -0
  43. package/models/command/shell/platform-common-shell-manifest.yaml +8 -0
  44. package/models/command/shell/platform-common-shell.yaml +8 -0
  45. package/openspec-gates/check-tasks-complete.ts +44 -0
  46. package/openspec-gates/tsconfig.json +13 -0
  47. package/package.json +6 -1
  48. package/workflows/workflow-openspec-plan-verify.yaml +51 -0
  49. package/workflows/workflow-openspec-tasks-verify.yaml +51 -0
  50. package/workflows/workflow-pre-pr-verify.yaml +118 -0
@@ -8,10 +8,11 @@ const BootcampApplication_1 = require("./BootcampApplication");
8
8
  const CodeOwnersFile_1 = require("./CodeOwnersFile");
9
9
  const DataDogAspectFile_1 = require("./DataDogAspectFile");
10
10
  const GitHubRolesFile_1 = require("./GitHubRolesFile");
11
+ const SoftwareFactoryFiles_1 = require("./SoftwareFactoryFiles");
11
12
  const utils_1 = require("./utils");
12
13
  const ViteReactProject_1 = require("./ViteReactProject");
13
14
  class BootcampProject extends awscdk_1.AwsCdkTypeScriptApp {
14
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.BootcampProject", version: "1.17.2" };
15
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.BootcampProject", version: "1.18.0" };
15
16
  constructor(options) {
16
17
  super({
17
18
  ...options,
@@ -96,6 +97,11 @@ class BootcampProject extends awscdk_1.AwsCdkTypeScriptApp {
96
97
  additionalOwners: options.additionalCodeOwners,
97
98
  });
98
99
  new DataDogAspectFile_1.DataDogAspectFile(this);
100
+ new SoftwareFactoryFiles_1.SoftwareFactoryFiles(this, {
101
+ repoName: options.name,
102
+ baseBranch: options.defaultReleaseBranch,
103
+ actionVersions: options.actionVersions,
104
+ });
99
105
  const viteReact = new ViteReactProject_1.ViteReactProject({
100
106
  name: options.name,
101
107
  defaultReleaseBranch: 'main',
@@ -118,4 +124,4 @@ class BootcampProject extends awscdk_1.AwsCdkTypeScriptApp {
118
124
  }
119
125
  }
120
126
  exports.BootcampProject = BootcampProject;
121
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm9vdGNhbXBQcm9qZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0Jvb3RjYW1wUHJvamVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsOENBQXdEO0FBQ3hELDhDQUFzRDtBQUV0RCwrREFBNEQ7QUFDNUQscURBQWtEO0FBQ2xELDJEQUF3RDtBQUN4RCx1REFBb0Q7QUFDcEQsbUNBQXlDO0FBQ3pDLHlEQUFzRDtBQU90RCxNQUFhLGVBQWdCLFNBQVEsNEJBQW1COztJQUN0RCxZQUFZLE9BQStCO1FBQ3pDLEtBQUssQ0FBQztZQUNKLEdBQUcsT0FBTztZQUNWLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVSxJQUFJLFNBQVM7WUFDM0Msb0JBQW9CLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixJQUFJLE1BQU07WUFDNUQsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO1lBQ2xCLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLGFBQWEsRUFBRSxLQUFLO1lBQ3BCLElBQUksRUFBRTtnQkFDSixtQkFBbUI7Z0JBQ25CLGdCQUFnQjtnQkFDaEIsV0FBVztnQkFDWCxJQUFJO2dCQUNKLHFCQUFxQjtnQkFDckIsc0JBQXNCO2dCQUN0QiwyQkFBMkI7Z0JBQzNCLDBCQUEwQjtnQkFDMUIsbUNBQW1DO2dCQUNuQyxjQUFjO2dCQUNkLGlDQUFpQztnQkFDakMsU0FBUztnQkFDVCxpQkFBaUI7Z0JBQ2pCLGFBQWE7Z0JBQ2IsR0FBRyxPQUFPLENBQUMsSUFBSSxJQUFJLEVBQUU7YUFDdEI7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AscUJBQXFCO2dCQUNyQixTQUFTO2dCQUNULGNBQWM7Z0JBQ2QscUNBQXFDO2dCQUNyQyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksRUFBRTthQUN6QjtZQUNELFNBQVMsRUFBRTtnQkFDVCxtREFBbUQ7Z0JBQ25ELGNBQWM7Z0JBQ2QsR0FBRyxPQUFPLENBQUMsU0FBUyxJQUFJLEVBQUU7YUFDM0I7WUFDRCxRQUFRLEVBQUU7Z0JBQ1IsR0FBRyxPQUFPLENBQUMsUUFBUTtnQkFDbkIsZUFBZSxFQUFFO29CQUNmLEdBQUcsT0FBTyxDQUFDLFFBQVEsRUFBRSxlQUFlO29CQUNwQyxlQUFlLEVBQUUsSUFBSTtvQkFDckIsMEJBQTBCLEVBQUUsSUFBSTtpQkFDakM7YUFDRjtZQUNELFVBQVUsRUFBRSxLQUFLO1lBQ2pCLGNBQWMsRUFBRSxPQUFPLENBQUMsY0FBYyxJQUFJLElBQUk7WUFDOUMsa0JBQWtCLEVBQUU7Z0JBQ2xCLGVBQWUsRUFBRTtvQkFDZixpQkFBaUIsRUFBRSwwQkFBaUIsQ0FBQyx1QkFBdUIsQ0FBQzt3QkFDM0QsTUFBTSxFQUFFLGNBQWM7cUJBQ3ZCLENBQUM7aUJBQ0g7YUFDRjtZQUNELE1BQU0sRUFBRTtnQkFDTixRQUFRLEVBQUUsSUFBQSxzQkFBYyxFQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7YUFDdkM7U0FDRixDQUFDLENBQUM7UUFHSCxnQ0FBZ0M7UUFDaEMsTUFBTSxlQUFlLEdBQUcsY0FBYyxDQUFDO1FBQ3ZDLE1BQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQztRQUVuQyxJQUFJLHlDQUFtQixDQUFDLElBQUksRUFBRTtZQUM1QixnQkFBZ0IsRUFBRSx3QkFBd0IsT0FBTyxDQUFDLElBQUksRUFBRTtZQUN4RCxHQUFHLEVBQUU7Z0JBQ0gsR0FBRyxPQUFPLENBQUMsR0FBRzthQUNmO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLEdBQUcsT0FBTyxDQUFDLE9BQU87YUFDbkI7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osR0FBRyxPQUFPLENBQUMsR0FBRzthQUNmO1lBQ0QsY0FBYyxFQUFFLE9BQU8sQ0FBQyxjQUFjO1lBQ3RDLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtZQUNsQyxjQUFjLEVBQUUsT0FBTyxDQUFDLGNBQWM7U0FDdkMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxpQ0FBZSxDQUFDLElBQUksRUFBRTtZQUN4QixPQUFPLEVBQUUsZUFBZTtZQUN4QixhQUFhLEVBQUUsY0FBYztTQUM5QixDQUFDLENBQUM7UUFFSCxJQUFJLCtCQUFjLENBQUMsSUFBSSxFQUFFO1lBQ3ZCLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxvQkFBb0I7U0FDL0MsQ0FBQyxDQUFDO1FBRUgsSUFBSSxxQ0FBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU1QixNQUFNLFNBQVMsR0FBRyxJQUFJLG1DQUFnQixDQUFDO1lBQ3JDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtZQUNsQixvQkFBb0IsRUFBRSxNQUFNO1lBQzVCLE1BQU0sRUFBRSxJQUFJO1lBQ1osTUFBTSxFQUFFLEtBQUs7WUFDYixJQUFJLEVBQUUsT0FBTyxDQUFDLFdBQVc7U0FDMUIsQ0FBQyxDQUFDO1FBQ0gsU0FBUyxDQUFDLGNBQWMsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDaEQsU0FBUyxDQUFDLGNBQWMsQ0FBQyxlQUFlLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFcEQsTUFBTSxZQUFZLEdBQUcsQ0FBQyxHQUFHLElBQWMsRUFBRSxFQUFFO1lBQ3pDLE9BQU8sZ0JBQWdCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDN0QsQ0FBQyxDQUFDO1FBRUYsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUU7WUFDbEIsSUFBSSxFQUFFLFlBQVksQ0FDaEIsZ0ZBQWdGLEVBQ2hGLFNBQVMsQ0FBQyxVQUFVLENBQ3JCO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDdEIsSUFBSSxFQUFFLDJFQUEyRTtZQUNqRixXQUFXLEVBQUUsSUFBSTtTQUNsQixDQUFDLENBQUM7SUFHTCxDQUFDOztBQXZISCwwQ0F3SEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBd3NDZGtUeXBlU2NyaXB0QXBwIH0gZnJvbSAncHJvamVuL2xpYi9hd3NjZGsnO1xuaW1wb3J0IHsgR2l0aHViQ3JlZGVudGlhbHMgfSBmcm9tICdwcm9qZW4vbGliL2dpdGh1Yic7XG5pbXBvcnQgeyBCYXRtYW5Qcm9qZWN0T3B0aW9ucyB9IGZyb20gJy4vQmF0bWFuUHJvamVjdCc7XG5pbXBvcnQgeyBCb290Y2FtcEFwcGxpY2F0aW9uIH0gZnJvbSAnLi9Cb290Y2FtcEFwcGxpY2F0aW9uJztcbmltcG9ydCB7IENvZGVPd25lcnNGaWxlIH0gZnJvbSAnLi9Db2RlT3duZXJzRmlsZSc7XG5pbXBvcnQgeyBEYXRhRG9nQXNwZWN0RmlsZSB9IGZyb20gJy4vRGF0YURvZ0FzcGVjdEZpbGUnO1xuaW1wb3J0IHsgR2l0SHViUm9sZXNGaWxlIH0gZnJvbSAnLi9HaXRIdWJSb2xlc0ZpbGUnO1xuaW1wb3J0IHsgcmVhZG1lQ29udGVudHMgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IFZpdGVSZWFjdFByb2plY3QgfSBmcm9tICcuL1ZpdGVSZWFjdFByb2plY3QnO1xuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQm9vdGNhbXBQcm9qZWN0T3B0aW9ucyBleHRlbmRzIEJhdG1hblByb2plY3RPcHRpb25zIHtcblxufVxuXG5leHBvcnQgY2xhc3MgQm9vdGNhbXBQcm9qZWN0IGV4dGVuZHMgQXdzQ2RrVHlwZVNjcmlwdEFwcCB7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEJvb3RjYW1wUHJvamVjdE9wdGlvbnMpIHtcbiAgICBzdXBlcih7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgY2RrVmVyc2lvbjogb3B0aW9ucy5jZGtWZXJzaW9uIHx8ICcyLjIyNC4wJyxcbiAgICAgIGRlZmF1bHRSZWxlYXNlQnJhbmNoOiBvcHRpb25zLmRlZmF1bHRSZWxlYXNlQnJhbmNoIHx8ICdtYWluJyxcbiAgICAgIG5hbWU6IG9wdGlvbnMubmFtZSxcbiAgICAgIHByb2plbnJjVHM6IHRydWUsXG4gICAgICBidWlsZFdvcmtmbG93OiBmYWxzZSxcbiAgICAgIGRlcHM6IFtcbiAgICAgICAgJ0B0eXBlcy9hd3MtbGFtYmRhJyxcbiAgICAgICAgJ0B0eXBlcy9leHByZXNzJyxcbiAgICAgICAgJ0B0eXBlcy9wZycsXG4gICAgICAgICdwZycsXG4gICAgICAgICdAYXdzLXNkay9yZHMtc2lnbmVyJyxcbiAgICAgICAgJ0BtYXR0aGV3Ym9uaWcvc2VjcmV0JyxcbiAgICAgICAgJ2RhdGFkb2ctY2RrLWNvbnN0cnVjdHMtdjInLFxuICAgICAgICAnQGNka2xhYnMvYXdzLWxhbWJkYS1ydXN0JyxcbiAgICAgICAgJ0Bhd3MtbGFtYmRhLXBvd2VydG9vbHMvcGFyYW1ldGVycycsXG4gICAgICAgICdqc29ud2VidG9rZW4nLFxuICAgICAgICAnQGF3cy1zZGsvY2xpZW50LXNlY3JldHMtbWFuYWdlcicsXG4gICAgICAgICdleHByZXNzJyxcbiAgICAgICAgJ3NlcnZlcmxlc3MtaHR0cCcsXG4gICAgICAgICdjZGstcmRzLXNxbCcsXG4gICAgICAgIC4uLm9wdGlvbnMuZGVwcyB8fCBbXSxcbiAgICAgIF0sXG4gICAgICBkZXZEZXBzOiBbXG4gICAgICAgICdAdHlwZXMvanNvbndlYnRva2VuJyxcbiAgICAgICAgJ25vZGVtb24nLFxuICAgICAgICAnY29uY3VycmVudGx5JyxcbiAgICAgICAgJ0BtYWNlZG9uLXRlY2hub2xvZ2llcy9iYXRtYW5AXjEuMC4wJyxcbiAgICAgICAgLi4ub3B0aW9ucy5kZXZEZXBzIHx8IFtdLFxuICAgICAgXSxcbiAgICAgIGdpdGlnbm9yZTogW1xuICAgICAgICAnc3JjL2NvbnN0cnVjdHMvaGFuZGxlci9jbGVyay1hdXRob3JpemVyL3RhcmdldC8qKicsXG4gICAgICAgICcqKi8uRFNfU3RvcmUnLFxuICAgICAgICAuLi5vcHRpb25zLmdpdGlnbm9yZSB8fCBbXSxcbiAgICAgIF0sXG4gICAgICB0c2NvbmZpZzoge1xuICAgICAgICAuLi5vcHRpb25zLnRzY29uZmlnLFxuICAgICAgICBjb21waWxlck9wdGlvbnM6IHtcbiAgICAgICAgICAuLi5vcHRpb25zLnRzY29uZmlnPy5jb21waWxlck9wdGlvbnMsXG4gICAgICAgICAgaXNvbGF0ZWRNb2R1bGVzOiB0cnVlLFxuICAgICAgICAgIGFsbG93SW1wb3J0aW5nVHNFeHRlbnNpb25zOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHNhbXBsZUNvZGU6IGZhbHNlLFxuICAgICAgbWluTm9kZVZlcnNpb246IG9wdGlvbnMubWluTm9kZVZlcnNpb24gfHwgJzIyJyxcbiAgICAgIGRlcHNVcGdyYWRlT3B0aW9uczoge1xuICAgICAgICB3b3JrZmxvd09wdGlvbnM6IHtcbiAgICAgICAgICBwcm9qZW5DcmVkZW50aWFsczogR2l0aHViQ3JlZGVudGlhbHMuZnJvbVBlcnNvbmFsQWNjZXNzVG9rZW4oe1xuICAgICAgICAgICAgc2VjcmV0OiAnR0lUSFVCX1RPS0VOJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZWFkbWU6IHtcbiAgICAgICAgY29udGVudHM6IHJlYWRtZUNvbnRlbnRzKG9wdGlvbnMubmFtZSksXG4gICAgICB9LFxuICAgIH0pO1xuXG5cbiAgICAvLyBDcmVhdGUgc3RhbmRhcmQgcHJvamVjdCBmaWxlc1xuICAgIGNvbnN0IFBSSU1BUllfQUNDT1VOVCA9ICcwMTU5NTU4MTcyNjMnO1xuICAgIGNvbnN0IFBSSU1BUllfUkVHSU9OID0gJ3VzLWVhc3QtMSc7XG5cbiAgICBuZXcgQm9vdGNhbXBBcHBsaWNhdGlvbih0aGlzLCB7XG4gICAgICBnaXRodWJSZXBvc2l0b3J5OiBgbWFjZWRvbi10ZWNobm9sb2dpZXMvJHtvcHRpb25zLm5hbWV9YCxcbiAgICAgIGRldjoge1xuICAgICAgICAuLi5vcHRpb25zLmRldixcbiAgICAgIH0sXG4gICAgICBzdGFnaW5nOiB7XG4gICAgICAgIC4uLm9wdGlvbnMuc3RhZ2luZyxcbiAgICAgIH0sXG4gICAgICBwcm9kOiB7XG4gICAgICAgIC4uLm9wdGlvbnMuZGV2LFxuICAgICAgfSxcbiAgICAgIGFkZGl0aW9uYWxUYWdzOiBvcHRpb25zLmFkZGl0aW9uYWxUYWdzLFxuICAgICAgbjhuV29ya2Zsb3dzOiBvcHRpb25zLm44bldvcmtmbG93cyxcbiAgICAgIGFjdGlvblZlcnNpb25zOiBvcHRpb25zLmFjdGlvblZlcnNpb25zLFxuICAgIH0pO1xuXG4gICAgbmV3IEdpdEh1YlJvbGVzRmlsZSh0aGlzLCB7XG4gICAgICBhY2NvdW50OiBQUklNQVJZX0FDQ09VTlQsXG4gICAgICBwcmltYXJ5UmVnaW9uOiBQUklNQVJZX1JFR0lPTixcbiAgICB9KTtcblxuICAgIG5ldyBDb2RlT3duZXJzRmlsZSh0aGlzLCB7XG4gICAgICBhZGRpdGlvbmFsT3duZXJzOiBvcHRpb25zLmFkZGl0aW9uYWxDb2RlT3duZXJzLFxuICAgIH0pO1xuXG4gICAgbmV3IERhdGFEb2dBc3BlY3RGaWxlKHRoaXMpO1xuXG4gICAgY29uc3Qgdml0ZVJlYWN0ID0gbmV3IFZpdGVSZWFjdFByb2plY3Qoe1xuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgZGVmYXVsdFJlbGVhc2VCcmFuY2g6ICdtYWluJyxcbiAgICAgIHBhcmVudDogdGhpcyxcbiAgICAgIG91dGRpcjogJ3dlYicsXG4gICAgICBkZXBzOiBvcHRpb25zLndlYnNpdGVEZXBzLFxuICAgIH0pO1xuICAgIHZpdGVSZWFjdC5hZGRDb25maWdGaWVsZCgnc29tZXRoaW5nJywgJ251bWJlcicpO1xuICAgIHZpdGVSZWFjdC5hZGRDb25maWdGaWVsZCgnc29tZXRoaW5nRWxzZScsICdzdHJpbmcnKTtcblxuICAgIGNvbnN0IGNvbmN1cnJlbnRseSA9ICguLi5hcmdzOiBzdHJpbmdbXSkgPT4ge1xuICAgICAgcmV0dXJuIGBjb25jdXJyZW50bHkgJHthcmdzLm1hcChhID0+IGBcIiR7YX1cImApLmpvaW4oJyAnKX1gO1xuICAgIH07XG5cbiAgICB0aGlzLmFkZFRhc2soJ2RldicsIHtcbiAgICAgIGV4ZWM6IGNvbmN1cnJlbnRseShcbiAgICAgICAgJ25vZGVtb24gLS13YXRjaCAuL3NyYy9jb25zdHJ1Y3RzL2hhbmRsZXIgLS13YXRjaCAuL2xvY2FsL2Rldi50cyAuL2xvY2FsL2Rldi50cycsXG4gICAgICAgIHZpdGVSZWFjdC5kZXZDb21tYW5kLFxuICAgICAgKSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkVGFzaygnY2RrOmRldicsIHtcbiAgICAgIGV4ZWM6ICdjZGsgLWEgXCJucHggdHMtbm9kZSAtUCB0c2NvbmZpZy5qc29uIC0tcHJlZmVyLXRzLWV4dHMgc3JjL0xvY2FsRGV2QXBwLnRzXCInLFxuICAgICAgcmVjZWl2ZUFyZ3M6IHRydWUsXG4gICAgfSk7XG5cblxuICB9XG59XG4iXX0=
127
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm9vdGNhbXBQcm9qZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0Jvb3RjYW1wUHJvamVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsOENBQXdEO0FBQ3hELDhDQUFzRDtBQUV0RCwrREFBNEQ7QUFDNUQscURBQWtEO0FBQ2xELDJEQUF3RDtBQUN4RCx1REFBb0Q7QUFDcEQsaUVBQThEO0FBQzlELG1DQUF5QztBQUN6Qyx5REFBc0Q7QUFPdEQsTUFBYSxlQUFnQixTQUFRLDRCQUFtQjs7SUFDdEQsWUFBWSxPQUErQjtRQUN6QyxLQUFLLENBQUM7WUFDSixHQUFHLE9BQU87WUFDVixVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVUsSUFBSSxTQUFTO1lBQzNDLG9CQUFvQixFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsSUFBSSxNQUFNO1lBQzVELElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtZQUNsQixVQUFVLEVBQUUsSUFBSTtZQUNoQixhQUFhLEVBQUUsS0FBSztZQUNwQixJQUFJLEVBQUU7Z0JBQ0osbUJBQW1CO2dCQUNuQixnQkFBZ0I7Z0JBQ2hCLFdBQVc7Z0JBQ1gsSUFBSTtnQkFDSixxQkFBcUI7Z0JBQ3JCLHNCQUFzQjtnQkFDdEIsMkJBQTJCO2dCQUMzQiwwQkFBMEI7Z0JBQzFCLG1DQUFtQztnQkFDbkMsY0FBYztnQkFDZCxpQ0FBaUM7Z0JBQ2pDLFNBQVM7Z0JBQ1QsaUJBQWlCO2dCQUNqQixhQUFhO2dCQUNiLEdBQUcsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFO2FBQ3RCO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLHFCQUFxQjtnQkFDckIsU0FBUztnQkFDVCxjQUFjO2dCQUNkLHFDQUFxQztnQkFDckMsR0FBRyxPQUFPLENBQUMsT0FBTyxJQUFJLEVBQUU7YUFDekI7WUFDRCxTQUFTLEVBQUU7Z0JBQ1QsbURBQW1EO2dCQUNuRCxjQUFjO2dCQUNkLEdBQUcsT0FBTyxDQUFDLFNBQVMsSUFBSSxFQUFFO2FB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RTtZQUNqRixXQUFXLEVBQUUsSUFBSTtTQUNsQixDQUFDLENBQUM7SUFHTCxDQUFDOztBQTdISCwwQ0E4SEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBd3NDZGtUeXBlU2NyaXB0QXBwIH0gZnJvbSAncHJvamVuL2xpYi9hd3NjZGsnO1xuaW1wb3J0IHsgR2l0aHViQ3JlZGVudGlhbHMgfSBmcm9tICdwcm9qZW4vbGliL2dpdGh1Yic7XG5pbXBvcnQgeyBCYXRtYW5Qcm9qZWN0T3B0aW9ucyB9IGZyb20gJy4vQmF0bWFuUHJvamVjdCc7XG5pbXBvcnQgeyBCb290Y2FtcEFwcGxpY2F0aW9uIH0gZnJvbSAnLi9Cb290Y2FtcEFwcGxpY2F0aW9uJztcbmltcG9ydCB7IENvZGVPd25lcnNGaWxlIH0gZnJvbSAnLi9Db2RlT3duZXJzRmlsZSc7XG5pbXBvcnQgeyBEYXRhRG9nQXNwZWN0RmlsZSB9IGZyb20gJy4vRGF0YURvZ0FzcGVjdEZpbGUnO1xuaW1wb3J0IHsgR2l0SHViUm9sZXNGaWxlIH0gZnJvbSAnLi9HaXRIdWJSb2xlc0ZpbGUnO1xuaW1wb3J0IHsgU29mdHdhcmVGYWN0b3J5RmlsZXMgfSBmcm9tICcuL1NvZnR3YXJlRmFjdG9yeUZpbGVzJztcbmltcG9ydCB7IHJlYWRtZUNvbnRlbnRzIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBWaXRlUmVhY3RQcm9qZWN0IH0gZnJvbSAnLi9WaXRlUmVhY3RQcm9qZWN0JztcblxuXG5leHBvcnQgaW50ZXJmYWNlIEJvb3RjYW1wUHJvamVjdE9wdGlvbnMgZXh0ZW5kcyBCYXRtYW5Qcm9qZWN0T3B0aW9ucyB7XG5cbn1cblxuZXhwb3J0IGNsYXNzIEJvb3RjYW1wUHJvamVjdCBleHRlbmRzIEF3c0Nka1R5cGVTY3JpcHRBcHAge1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBCb290Y2FtcFByb2plY3RPcHRpb25zKSB7XG4gICAgc3VwZXIoe1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIGNka1ZlcnNpb246IG9wdGlvbnMuY2RrVmVyc2lvbiB8fCAnMi4yMjQuMCcsXG4gICAgICBkZWZhdWx0UmVsZWFzZUJyYW5jaDogb3B0aW9ucy5kZWZhdWx0UmVsZWFzZUJyYW5jaCB8fCAnbWFpbicsXG4gICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICBwcm9qZW5yY1RzOiB0cnVlLFxuICAgICAgYnVpbGRXb3JrZmxvdzogZmFsc2UsXG4gICAgICBkZXBzOiBbXG4gICAgICAgICdAdHlwZXMvYXdzLWxhbWJkYScsXG4gICAgICAgICdAdHlwZXMvZXhwcmVzcycsXG4gICAgICAgICdAdHlwZXMvcGcnLFxuICAgICAgICAncGcnLFxuICAgICAgICAnQGF3cy1zZGsvcmRzLXNpZ25lcicsXG4gICAgICAgICdAbWF0dGhld2JvbmlnL3NlY3JldCcsXG4gICAgICAgICdkYXRhZG9nLWNkay1jb25zdHJ1Y3RzLXYyJyxcbiAgICAgICAgJ0BjZGtsYWJzL2F3cy1sYW1iZGEtcnVzdCcsXG4gICAgICAgICdAYXdzLWxhbWJkYS1wb3dlcnRvb2xzL3BhcmFtZXRlcnMnLFxuICAgICAgICAnanNvbndlYnRva2VuJyxcbiAgICAgICAgJ0Bhd3Mtc2RrL2NsaWVudC1zZWNyZXRzLW1hbmFnZXInLFxuICAgICAgICAnZXhwcmVzcycsXG4gICAgICAgICdzZXJ2ZXJsZXNzLWh0dHAnLFxuICAgICAgICAnY2RrLXJkcy1zcWwnLFxuICAgICAgICAuLi5vcHRpb25zLmRlcHMgfHwgW10sXG4gICAgICBdLFxuICAgICAgZGV2RGVwczogW1xuICAgICAgICAnQHR5cGVzL2pzb253ZWJ0b2tlbicsXG4gICAgICAgICdub2RlbW9uJyxcbiAgICAgICAgJ2NvbmN1cnJlbnRseScsXG4gICAgICAgICdAbWFjZWRvbi10ZWNobm9sb2dpZXMvYmF0bWFuQF4xLjAuMCcsXG4gICAgICAgIC4uLm9wdGlvbnMuZGV2RGVwcyB8fCBbXSxcbiAgICAgIF0sXG4gICAgICBnaXRpZ25vcmU6IFtcbiAgICAgICAgJ3NyYy9jb25zdHJ1Y3RzL2hhbmRsZXIvY2xlcmstYXV0aG9yaXplci90YXJnZXQvKionLFxuICAgICAgICAnKiovLkRTX1N0b3JlJyxcbiAgICAgICAgLi4ub3B0aW9ucy5naXRpZ25vcmUgfHwgW10sXG4gICAgICBdLFxuICAgICAgdHNjb25maWc6IHtcbiAgICAgICAgLi4ub3B0aW9ucy50c2NvbmZpZyxcbiAgICAgICAgY29tcGlsZXJPcHRpb25zOiB7XG4gICAgICAgICAgLi4ub3B0aW9ucy50c2NvbmZpZz8uY29tcGlsZXJPcHRpb25zLFxuICAgICAgICAgIGlzb2xhdGVkTW9kdWxlczogdHJ1ZSxcbiAgICAgICAgICBhbGxvd0ltcG9ydGluZ1RzRXh0ZW5zaW9uczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBzYW1wbGVDb2RlOiBmYWxzZSxcbiAgICAgIG1pbk5vZGVWZXJzaW9uOiBvcHRpb25zLm1pbk5vZGVWZXJzaW9uIHx8ICcyMicsXG4gICAgICBkZXBzVXBncmFkZU9wdGlvbnM6IHtcbiAgICAgICAgd29ya2Zsb3dPcHRpb25zOiB7XG4gICAgICAgICAgcHJvamVuQ3JlZGVudGlhbHM6IEdpdGh1YkNyZWRlbnRpYWxzLmZyb21QZXJzb25hbEFjY2Vzc1Rva2VuKHtcbiAgICAgICAgICAgIHNlY3JldDogJ0dJVEhVQl9UT0tFTicsXG4gICAgICAgICAgfSksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcmVhZG1lOiB7XG4gICAgICAgIGNvbnRlbnRzOiByZWFkbWVDb250ZW50cyhvcHRpb25zLm5hbWUpLFxuICAgICAgfSxcbiAgICB9KTtcblxuXG4gICAgLy8gQ3JlYXRlIHN0YW5kYXJkIHByb2plY3QgZmlsZXNcbiAgICBjb25zdCBQUklNQVJZX0FDQ09VTlQgPSAnMDE1OTU1ODE3MjYzJztcbiAgICBjb25zdCBQUklNQVJZX1JFR0lPTiA9ICd1cy1lYXN0LTEnO1xuXG4gICAgbmV3IEJvb3RjYW1wQXBwbGljYXRpb24odGhpcywge1xuICAgICAgZ2l0aHViUmVwb3NpdG9yeTogYG1hY2Vkb24tdGVjaG5vbG9naWVzLyR7b3B0aW9ucy5uYW1lfWAsXG4gICAgICBkZXY6IHtcbiAgICAgICAgLi4ub3B0aW9ucy5kZXYsXG4gICAgICB9LFxuICAgICAgc3RhZ2luZzoge1xuICAgICAgICAuLi5vcHRpb25zLnN0YWdpbmcsXG4gICAgICB9LFxuICAgICAgcHJvZDoge1xuICAgICAgICAuLi5vcHRpb25zLmRldixcbiAgICAgIH0sXG4gICAgICBhZGRpdGlvbmFsVGFnczogb3B0aW9ucy5hZGRpdGlvbmFsVGFncyxcbiAgICAgIG44bldvcmtmbG93czogb3B0aW9ucy5uOG5Xb3JrZmxvd3MsXG4gICAgICBhY3Rpb25WZXJzaW9uczogb3B0aW9ucy5hY3Rpb25WZXJzaW9ucyxcbiAgICB9KTtcblxuICAgIG5ldyBHaXRIdWJSb2xlc0ZpbGUodGhpcywge1xuICAgICAgYWNjb3VudDogUFJJTUFSWV9BQ0NPVU5ULFxuICAgICAgcHJpbWFyeVJlZ2lvbjogUFJJTUFSWV9SRUdJT04sXG4gICAgfSk7XG5cbiAgICBuZXcgQ29kZU93bmVyc0ZpbGUodGhpcywge1xuICAgICAgYWRkaXRpb25hbE93bmVyczogb3B0aW9ucy5hZGRpdGlvbmFsQ29kZU93bmVycyxcbiAgICB9KTtcblxuICAgIG5ldyBEYXRhRG9nQXNwZWN0RmlsZSh0aGlzKTtcblxuICAgIG5ldyBTb2Z0d2FyZUZhY3RvcnlGaWxlcyh0aGlzLCB7XG4gICAgICByZXBvTmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgYmFzZUJyYW5jaDogb3B0aW9ucy5kZWZhdWx0UmVsZWFzZUJyYW5jaCxcbiAgICAgIGFjdGlvblZlcnNpb25zOiBvcHRpb25zLmFjdGlvblZlcnNpb25zLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgdml0ZVJlYWN0ID0gbmV3IFZpdGVSZWFjdFByb2plY3Qoe1xuICAgICAgbmFtZTogb3B0aW9ucy5uYW1lLFxuICAgICAgZGVmYXVsdFJlbGVhc2VCcmFuY2g6ICdtYWluJyxcbiAgICAgIHBhcmVudDogdGhpcyxcbiAgICAgIG91dGRpcjogJ3dlYicsXG4gICAgICBkZXBzOiBvcHRpb25zLndlYnNpdGVEZXBzLFxuICAgIH0pO1xuICAgIHZpdGVSZWFjdC5hZGRDb25maWdGaWVsZCgnc29tZXRoaW5nJywgJ251bWJlcicpO1xuICAgIHZpdGVSZWFjdC5hZGRDb25maWdGaWVsZCgnc29tZXRoaW5nRWxzZScsICdzdHJpbmcnKTtcblxuICAgIGNvbnN0IGNvbmN1cnJlbnRseSA9ICguLi5hcmdzOiBzdHJpbmdbXSkgPT4ge1xuICAgICAgcmV0dXJuIGBjb25jdXJyZW50bHkgJHthcmdzLm1hcChhID0+IGBcIiR7YX1cImApLmpvaW4oJyAnKX1gO1xuICAgIH07XG5cbiAgICB0aGlzLmFkZFRhc2soJ2RldicsIHtcbiAgICAgIGV4ZWM6IGNvbmN1cnJlbnRseShcbiAgICAgICAgJ25vZGVtb24gLS13YXRjaCAuL3NyYy9jb25zdHJ1Y3RzL2hhbmRsZXIgLS13YXRjaCAuL2xvY2FsL2Rldi50cyAuL2xvY2FsL2Rldi50cycsXG4gICAgICAgIHZpdGVSZWFjdC5kZXZDb21tYW5kLFxuICAgICAgKSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkVGFzaygnY2RrOmRldicsIHtcbiAgICAgIGV4ZWM6ICdjZGsgLWEgXCJucHggdHMtbm9kZSAtUCB0c2NvbmZpZy5qc29uIC0tcHJlZmVyLXRzLWV4dHMgc3JjL0xvY2FsRGV2QXBwLnRzXCInLFxuICAgICAgcmVjZWl2ZUFyZ3M6IHRydWUsXG4gICAgfSk7XG5cblxuICB9XG59XG4iXX0=
@@ -4,7 +4,7 @@ exports.CodeOwnersFile = void 0;
4
4
  const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
5
5
  const projen_1 = require("projen");
6
6
  class CodeOwnersFile extends projen_1.TextFile {
7
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.CodeOwnersFile", version: "1.17.2" };
7
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.CodeOwnersFile", version: "1.18.0" };
8
8
  constructor(project, options = {}) {
9
9
  const defaultOwners = ['* @macedon-technologies/platform'];
10
10
  const allOwners = [...defaultOwners, ...(options.additionalOwners || [])];
@@ -7,7 +7,7 @@ const javascript_1 = require("projen/lib/javascript");
7
7
  const utils_1 = require("./utils");
8
8
  const WorkflowActionVersions_1 = require("./WorkflowActionVersions");
9
9
  class ProductionDeployWorkflow extends projen_1.YamlFile {
10
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.ProductionDeployWorkflow", version: "1.17.2" };
10
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.ProductionDeployWorkflow", version: "1.18.0" };
11
11
  constructor(project, options) {
12
12
  const packageManager = project.package.packageManager;
13
13
  const actionVersions = (0, WorkflowActionVersions_1.resolveActionVersions)(options.actionVersions);
@@ -0,0 +1,18 @@
1
+ import { AwsCdkTypeScriptApp } from 'projen/lib/awscdk';
2
+ import { WorkflowActionVersions } from './WorkflowActionVersions';
3
+ /**
4
+ * Hardens the GitHub Actions workflows that `AwsCdkTypeScriptApp` generates on its own
5
+ * (`upgrade.yml`, `pull-request-lint.yml`, ...) against the zizmor findings raised on
6
+ * consumer repos (e.g. macedon-technologies/exman#13).
7
+ *
8
+ * These workflows aren't hand-authored by this package the way `PrDeployWorkflow`/
9
+ * `PrCleanupWorkflow`/etc. are, so they can't be pinned by writing a literal SHA into a
10
+ * `uses:` string. projen exposes `project.github.actions` for exactly this case: every
11
+ * `uses:` rendered by a `GithubWorkflow`/`Job` (including projen's own built-in
12
+ * components) is resolved through it at synthesis time.
13
+ *
14
+ * `persist-credentials` and the `pull_request_target` trigger aren't covered by that
15
+ * registry (it only rewrites `uses:`), so those are corrected with a `JsonPatch` against
16
+ * the synthesized workflow file instead.
17
+ */
18
+ export declare function hardenProjenGeneratedWorkflows(project: AwsCdkTypeScriptApp, actionVersions?: WorkflowActionVersions): void;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hardenProjenGeneratedWorkflows = hardenProjenGeneratedWorkflows;
4
+ const projen_1 = require("projen");
5
+ const WorkflowActionVersions_1 = require("./WorkflowActionVersions");
6
+ /**
7
+ * Hardens the GitHub Actions workflows that `AwsCdkTypeScriptApp` generates on its own
8
+ * (`upgrade.yml`, `pull-request-lint.yml`, ...) against the zizmor findings raised on
9
+ * consumer repos (e.g. macedon-technologies/exman#13).
10
+ *
11
+ * These workflows aren't hand-authored by this package the way `PrDeployWorkflow`/
12
+ * `PrCleanupWorkflow`/etc. are, so they can't be pinned by writing a literal SHA into a
13
+ * `uses:` string. projen exposes `project.github.actions` for exactly this case: every
14
+ * `uses:` rendered by a `GithubWorkflow`/`Job` (including projen's own built-in
15
+ * components) is resolved through it at synthesis time.
16
+ *
17
+ * `persist-credentials` and the `pull_request_target` trigger aren't covered by that
18
+ * registry (it only rewrites `uses:`), so those are corrected with a `JsonPatch` against
19
+ * the synthesized workflow file instead.
20
+ */
21
+ function hardenProjenGeneratedWorkflows(project, actionVersions) {
22
+ const versions = (0, WorkflowActionVersions_1.resolveActionVersions)(actionVersions);
23
+ const github = project.github;
24
+ if (!github) {
25
+ return;
26
+ }
27
+ // zizmor: unpinned-uses (high) — projen's built-in workflows reference these actions by
28
+ // mutable tag (e.g. `actions/checkout@v6`). Overriding by bare action name repoints every
29
+ // usage projen renders, without touching the hand-authored workflows above (which already
30
+ // embed a resolved SHA literal and never go through this registry). upload-artifact,
31
+ // download-artifact and action-semantic-pull-request weren't reported in #13, but are the
32
+ // same finding on the same two files, so they're pinned here too rather than left ticking.
33
+ github.actions.set('actions/checkout', versions.checkout);
34
+ github.actions.set('actions/setup-node', versions.setupNode);
35
+ github.actions.set('pnpm/action-setup', versions.pnpmActionSetup);
36
+ github.actions.set('actions/github-script', versions.githubScript);
37
+ github.actions.set('peter-evans/create-pull-request', versions.createPullRequest);
38
+ github.actions.set('actions/upload-artifact', versions.uploadArtifact);
39
+ github.actions.set('actions/download-artifact', versions.downloadArtifact);
40
+ github.actions.set('amannn/action-semantic-pull-request', versions.semanticPullRequest);
41
+ // zizmor: artipacked (low) — actions/checkout persists git credentials to disk by
42
+ // default. Neither of upgrade.yml's checkout steps need to push from that checkout
43
+ // (the "pr" job's push happens via peter-evans/create-pull-request with its own token).
44
+ const upgrade = github.tryFindWorkflow('upgrade');
45
+ upgrade?.file?.patch(projen_1.JsonPatch.add('/jobs/upgrade/steps/0/with', { 'persist-credentials': false }), projen_1.JsonPatch.add('/jobs/pr/steps/0/with', { 'persist-credentials': false }));
46
+ // zizmor: dangerous-triggers (high) — pull-request-lint.yml only validates the PR title;
47
+ // it doesn't need pull_request_target's access to secrets/write permissions against
48
+ // untrusted fork content. `pull_request` covers the same title-changed events without
49
+ // the risk. (If a consumer ever needs this check to comment on forked PRs, that consumer
50
+ // should override `pullRequestLintOptions` accordingly instead of reverting this globally.)
51
+ const pullRequestLint = github.tryFindWorkflow('pull-request-lint');
52
+ pullRequestLint?.file?.patch(projen_1.JsonPatch.replace('/on', {
53
+ pull_request: {
54
+ types: ['labeled', 'opened', 'synchronize', 'reopened', 'ready_for_review', 'edited'],
55
+ },
56
+ merge_group: {},
57
+ }));
58
+ }
59
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJvamVuV29ya2Zsb3dIYXJkZW5pbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvUHJvamVuV29ya2Zsb3dIYXJkZW5pbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFtQkEsd0VBNkNDO0FBaEVELG1DQUFtQztBQUVuQyxxRUFBeUY7QUFFekY7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxTQUFnQiw4QkFBOEIsQ0FBQyxPQUE0QixFQUFFLGNBQXVDO0lBQ2xILE1BQU0sUUFBUSxHQUFHLElBQUEsOENBQXFCLEVBQUMsY0FBYyxDQUFDLENBQUM7SUFDdkQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUM5QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixPQUFPO0lBQ1QsQ0FBQztJQUVELHdGQUF3RjtJQUN4RiwwRkFBMEY7SUFDMUYsMEZBQTBGO0lBQzFGLHFGQUFxRjtJQUNyRiwwRkFBMEY7SUFDMUYsMkZBQTJGO0lBQzNGLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMxRCxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0QsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2xFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixFQUFFLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNuRSxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsRUFBRSxRQUFRLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNsRixNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDdkUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLEVBQUUsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDM0UsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMscUNBQXFDLEVBQUUsUUFBUSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFFeEYsa0ZBQWtGO0lBQ2xGLG1GQUFtRjtJQUNuRix3RkFBd0Y7SUFDeEYsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNsRCxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FDbEIsa0JBQVMsQ0FBQyxHQUFHLENBQUMsNEJBQTRCLEVBQUUsRUFBRSxxQkFBcUIsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUM3RSxrQkFBUyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsRUFBRSxFQUFFLHFCQUFxQixFQUFFLEtBQUssRUFBRSxDQUFDLENBQ3pFLENBQUM7SUFFRix5RkFBeUY7SUFDekYsb0ZBQW9GO0lBQ3BGLHNGQUFzRjtJQUN0Rix5RkFBeUY7SUFDekYsNEZBQTRGO0lBQzVGLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUNwRSxlQUFlLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FDMUIsa0JBQVMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFO1FBQ3ZCLFlBQVksRUFBRTtZQUNaLEtBQUssRUFBRSxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxrQkFBa0IsRUFBRSxRQUFRLENBQUM7U0FDdEY7UUFDRCxXQUFXLEVBQUUsRUFBRTtLQUNoQixDQUFDLENBQ0gsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBKc29uUGF0Y2ggfSBmcm9tICdwcm9qZW4nO1xuaW1wb3J0IHsgQXdzQ2RrVHlwZVNjcmlwdEFwcCB9IGZyb20gJ3Byb2plbi9saWIvYXdzY2RrJztcbmltcG9ydCB7IHJlc29sdmVBY3Rpb25WZXJzaW9ucywgV29ya2Zsb3dBY3Rpb25WZXJzaW9ucyB9IGZyb20gJy4vV29ya2Zsb3dBY3Rpb25WZXJzaW9ucyc7XG5cbi8qKlxuICogSGFyZGVucyB0aGUgR2l0SHViIEFjdGlvbnMgd29ya2Zsb3dzIHRoYXQgYEF3c0Nka1R5cGVTY3JpcHRBcHBgIGdlbmVyYXRlcyBvbiBpdHMgb3duXG4gKiAoYHVwZ3JhZGUueW1sYCwgYHB1bGwtcmVxdWVzdC1saW50LnltbGAsIC4uLikgYWdhaW5zdCB0aGUgeml6bW9yIGZpbmRpbmdzIHJhaXNlZCBvblxuICogY29uc3VtZXIgcmVwb3MgKGUuZy4gbWFjZWRvbi10ZWNobm9sb2dpZXMvZXhtYW4jMTMpLlxuICpcbiAqIFRoZXNlIHdvcmtmbG93cyBhcmVuJ3QgaGFuZC1hdXRob3JlZCBieSB0aGlzIHBhY2thZ2UgdGhlIHdheSBgUHJEZXBsb3lXb3JrZmxvd2AvXG4gKiBgUHJDbGVhbnVwV29ya2Zsb3dgL2V0Yy4gYXJlLCBzbyB0aGV5IGNhbid0IGJlIHBpbm5lZCBieSB3cml0aW5nIGEgbGl0ZXJhbCBTSEEgaW50byBhXG4gKiBgdXNlczpgIHN0cmluZy4gcHJvamVuIGV4cG9zZXMgYHByb2plY3QuZ2l0aHViLmFjdGlvbnNgIGZvciBleGFjdGx5IHRoaXMgY2FzZTogZXZlcnlcbiAqIGB1c2VzOmAgcmVuZGVyZWQgYnkgYSBgR2l0aHViV29ya2Zsb3dgL2BKb2JgIChpbmNsdWRpbmcgcHJvamVuJ3Mgb3duIGJ1aWx0LWluXG4gKiBjb21wb25lbnRzKSBpcyByZXNvbHZlZCB0aHJvdWdoIGl0IGF0IHN5bnRoZXNpcyB0aW1lLlxuICpcbiAqIGBwZXJzaXN0LWNyZWRlbnRpYWxzYCBhbmQgdGhlIGBwdWxsX3JlcXVlc3RfdGFyZ2V0YCB0cmlnZ2VyIGFyZW4ndCBjb3ZlcmVkIGJ5IHRoYXRcbiAqIHJlZ2lzdHJ5IChpdCBvbmx5IHJld3JpdGVzIGB1c2VzOmApLCBzbyB0aG9zZSBhcmUgY29ycmVjdGVkIHdpdGggYSBgSnNvblBhdGNoYCBhZ2FpbnN0XG4gKiB0aGUgc3ludGhlc2l6ZWQgd29ya2Zsb3cgZmlsZSBpbnN0ZWFkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFyZGVuUHJvamVuR2VuZXJhdGVkV29ya2Zsb3dzKHByb2plY3Q6IEF3c0Nka1R5cGVTY3JpcHRBcHAsIGFjdGlvblZlcnNpb25zPzogV29ya2Zsb3dBY3Rpb25WZXJzaW9ucyk6IHZvaWQge1xuICBjb25zdCB2ZXJzaW9ucyA9IHJlc29sdmVBY3Rpb25WZXJzaW9ucyhhY3Rpb25WZXJzaW9ucyk7XG4gIGNvbnN0IGdpdGh1YiA9IHByb2plY3QuZ2l0aHViO1xuICBpZiAoIWdpdGh1Yikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIHppem1vcjogdW5waW5uZWQtdXNlcyAoaGlnaCkg4oCUIHByb2plbidzIGJ1aWx0LWluIHdvcmtmbG93cyByZWZlcmVuY2UgdGhlc2UgYWN0aW9ucyBieVxuICAvLyBtdXRhYmxlIHRhZyAoZS5nLiBgYWN0aW9ucy9jaGVja291dEB2NmApLiBPdmVycmlkaW5nIGJ5IGJhcmUgYWN0aW9uIG5hbWUgcmVwb2ludHMgZXZlcnlcbiAgLy8gdXNhZ2UgcHJvamVuIHJlbmRlcnMsIHdpdGhvdXQgdG91Y2hpbmcgdGhlIGhhbmQtYXV0aG9yZWQgd29ya2Zsb3dzIGFib3ZlICh3aGljaCBhbHJlYWR5XG4gIC8vIGVtYmVkIGEgcmVzb2x2ZWQgU0hBIGxpdGVyYWwgYW5kIG5ldmVyIGdvIHRocm91Z2ggdGhpcyByZWdpc3RyeSkuIHVwbG9hZC1hcnRpZmFjdCxcbiAgLy8gZG93bmxvYWQtYXJ0aWZhY3QgYW5kIGFjdGlvbi1zZW1hbnRpYy1wdWxsLXJlcXVlc3Qgd2VyZW4ndCByZXBvcnRlZCBpbiAjMTMsIGJ1dCBhcmUgdGhlXG4gIC8vIHNhbWUgZmluZGluZyBvbiB0aGUgc2FtZSB0d28gZmlsZXMsIHNvIHRoZXkncmUgcGlubmVkIGhlcmUgdG9vIHJhdGhlciB0aGFuIGxlZnQgdGlja2luZy5cbiAgZ2l0aHViLmFjdGlvbnMuc2V0KCdhY3Rpb25zL2NoZWNrb3V0JywgdmVyc2lvbnMuY2hlY2tvdXQpO1xuICBnaXRodWIuYWN0aW9ucy5zZXQoJ2FjdGlvbnMvc2V0dXAtbm9kZScsIHZlcnNpb25zLnNldHVwTm9kZSk7XG4gIGdpdGh1Yi5hY3Rpb25zLnNldCgncG5wbS9hY3Rpb24tc2V0dXAnLCB2ZXJzaW9ucy5wbnBtQWN0aW9uU2V0dXApO1xuICBnaXRodWIuYWN0aW9ucy5zZXQoJ2FjdGlvbnMvZ2l0aHViLXNjcmlwdCcsIHZlcnNpb25zLmdpdGh1YlNjcmlwdCk7XG4gIGdpdGh1Yi5hY3Rpb25zLnNldCgncGV0ZXItZXZhbnMvY3JlYXRlLXB1bGwtcmVxdWVzdCcsIHZlcnNpb25zLmNyZWF0ZVB1bGxSZXF1ZXN0KTtcbiAgZ2l0aHViLmFjdGlvbnMuc2V0KCdhY3Rpb25zL3VwbG9hZC1hcnRpZmFjdCcsIHZlcnNpb25zLnVwbG9hZEFydGlmYWN0KTtcbiAgZ2l0aHViLmFjdGlvbnMuc2V0KCdhY3Rpb25zL2Rvd25sb2FkLWFydGlmYWN0JywgdmVyc2lvbnMuZG93bmxvYWRBcnRpZmFjdCk7XG4gIGdpdGh1Yi5hY3Rpb25zLnNldCgnYW1hbm5uL2FjdGlvbi1zZW1hbnRpYy1wdWxsLXJlcXVlc3QnLCB2ZXJzaW9ucy5zZW1hbnRpY1B1bGxSZXF1ZXN0KTtcblxuICAvLyB6aXptb3I6IGFydGlwYWNrZWQgKGxvdykg4oCUIGFjdGlvbnMvY2hlY2tvdXQgcGVyc2lzdHMgZ2l0IGNyZWRlbnRpYWxzIHRvIGRpc2sgYnlcbiAgLy8gZGVmYXVsdC4gTmVpdGhlciBvZiB1cGdyYWRlLnltbCdzIGNoZWNrb3V0IHN0ZXBzIG5lZWQgdG8gcHVzaCBmcm9tIHRoYXQgY2hlY2tvdXRcbiAgLy8gKHRoZSBcInByXCIgam9iJ3MgcHVzaCBoYXBwZW5zIHZpYSBwZXRlci1ldmFucy9jcmVhdGUtcHVsbC1yZXF1ZXN0IHdpdGggaXRzIG93biB0b2tlbikuXG4gIGNvbnN0IHVwZ3JhZGUgPSBnaXRodWIudHJ5RmluZFdvcmtmbG93KCd1cGdyYWRlJyk7XG4gIHVwZ3JhZGU/LmZpbGU/LnBhdGNoKFxuICAgIEpzb25QYXRjaC5hZGQoJy9qb2JzL3VwZ3JhZGUvc3RlcHMvMC93aXRoJywgeyAncGVyc2lzdC1jcmVkZW50aWFscyc6IGZhbHNlIH0pLFxuICAgIEpzb25QYXRjaC5hZGQoJy9qb2JzL3ByL3N0ZXBzLzAvd2l0aCcsIHsgJ3BlcnNpc3QtY3JlZGVudGlhbHMnOiBmYWxzZSB9KSxcbiAgKTtcblxuICAvLyB6aXptb3I6IGRhbmdlcm91cy10cmlnZ2VycyAoaGlnaCkg4oCUIHB1bGwtcmVxdWVzdC1saW50LnltbCBvbmx5IHZhbGlkYXRlcyB0aGUgUFIgdGl0bGU7XG4gIC8vIGl0IGRvZXNuJ3QgbmVlZCBwdWxsX3JlcXVlc3RfdGFyZ2V0J3MgYWNjZXNzIHRvIHNlY3JldHMvd3JpdGUgcGVybWlzc2lvbnMgYWdhaW5zdFxuICAvLyB1bnRydXN0ZWQgZm9yayBjb250ZW50LiBgcHVsbF9yZXF1ZXN0YCBjb3ZlcnMgdGhlIHNhbWUgdGl0bGUtY2hhbmdlZCBldmVudHMgd2l0aG91dFxuICAvLyB0aGUgcmlzay4gKElmIGEgY29uc3VtZXIgZXZlciBuZWVkcyB0aGlzIGNoZWNrIHRvIGNvbW1lbnQgb24gZm9ya2VkIFBScywgdGhhdCBjb25zdW1lclxuICAvLyBzaG91bGQgb3ZlcnJpZGUgYHB1bGxSZXF1ZXN0TGludE9wdGlvbnNgIGFjY29yZGluZ2x5IGluc3RlYWQgb2YgcmV2ZXJ0aW5nIHRoaXMgZ2xvYmFsbHkuKVxuICBjb25zdCBwdWxsUmVxdWVzdExpbnQgPSBnaXRodWIudHJ5RmluZFdvcmtmbG93KCdwdWxsLXJlcXVlc3QtbGludCcpO1xuICBwdWxsUmVxdWVzdExpbnQ/LmZpbGU/LnBhdGNoKFxuICAgIEpzb25QYXRjaC5yZXBsYWNlKCcvb24nLCB7XG4gICAgICBwdWxsX3JlcXVlc3Q6IHtcbiAgICAgICAgdHlwZXM6IFsnbGFiZWxlZCcsICdvcGVuZWQnLCAnc3luY2hyb25pemUnLCAncmVvcGVuZWQnLCAncmVhZHlfZm9yX3JldmlldycsICdlZGl0ZWQnXSxcbiAgICAgIH0sXG4gICAgICBtZXJnZV9ncm91cDoge30sXG4gICAgfSksXG4gICk7XG59XG4iXX0=
@@ -0,0 +1,10 @@
1
+ import { NodeProject } from 'projen/lib/javascript';
2
+ /**
3
+ * The generic, data-driven architecture rule engine plus an empty seed
4
+ * rules.json. `check.ts`/`tsconfig.json`/`README.md` are managed (Batman
5
+ * owns the engine); `rules.json` is a `SampleFile` — each repo's own rules
6
+ * are data the team owns, not something Batman should overwrite.
7
+ */
8
+ export declare class SoftwareFactoryArchitectureRules {
9
+ constructor(project: NodeProject);
10
+ }
@@ -0,0 +1,245 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SoftwareFactoryArchitectureRules = void 0;
4
+ const projen_1 = require("projen");
5
+ /**
6
+ * The generic, data-driven architecture rule engine plus an empty seed
7
+ * rules.json. `check.ts`/`tsconfig.json`/`README.md` are managed (Batman
8
+ * owns the engine); `rules.json` is a `SampleFile` — each repo's own rules
9
+ * are data the team owns, not something Batman should overwrite.
10
+ */
11
+ class SoftwareFactoryArchitectureRules {
12
+ constructor(project) {
13
+ new projen_1.TextFile(project, 'architecture-rules/check.ts', {
14
+ marker: true,
15
+ lines: [
16
+ '/**',
17
+ ' * Generic architecture-rule engine. Rules live entirely in rules.json — this',
18
+ ' * file only knows how to evaluate the check "types" that rules can declare.',
19
+ ' * Add a new rule by adding a rules.json entry; add a new check type by adding',
20
+ ' * a case in evaluateRule().',
21
+ ' */',
22
+ "import * as fs from 'node:fs';",
23
+ "import * as path from 'node:path';",
24
+ "import rulesFile from './rules.json';",
25
+ '',
26
+ 'interface ForbiddenImportCheck {',
27
+ " type: 'forbidden-import';",
28
+ ' // Glob patterns (relative to repo root) selecting the files this rule inspects.',
29
+ ' from: string[];',
30
+ ' // Glob patterns (relative to repo root) that "from" files may not import from.',
31
+ ' forbid: string[];',
32
+ '}',
33
+ '',
34
+ 'interface Rule {',
35
+ ' id: string;',
36
+ ' description: string;',
37
+ ' enabled: boolean;',
38
+ " severity: 'low' | 'medium' | 'high' | 'critical';",
39
+ ' check: ForbiddenImportCheck;',
40
+ '}',
41
+ '',
42
+ 'interface Violation {',
43
+ ' ruleId: string;',
44
+ ' severity: string;',
45
+ ' message: string;',
46
+ '}',
47
+ '',
48
+ "const REPO_ROOT = path.resolve(__dirname, '..');",
49
+ "const IGNORED_DIRS = new Set(['node_modules', '.git', '.swamp', 'cdk.out', 'lib', 'build', 'dist']);",
50
+ '',
51
+ '// Minimal glob -> RegExp: supports "*", "**", "**/" and literal path segments.',
52
+ '// No new dependency for this — the only pattern shapes rules.json ever needs',
53
+ '// are directory-prefix globs like "src/domains/*/commands/**".',
54
+ 'function globToRegExp(glob: string): RegExp {',
55
+ " let out = '';",
56
+ ' for (let i = 0; i < glob.length; i++) {',
57
+ ' const c = glob[i];',
58
+ " if (c === '*' && glob[i + 1] === '*') {",
59
+ ' i++;',
60
+ " if (glob[i + 1] === '/') {",
61
+ " out += '(?:.*/)?';",
62
+ ' i++;',
63
+ ' } else {',
64
+ " out += '.*';",
65
+ ' }',
66
+ " } else if (c === '*') {",
67
+ " out += '[^/]*';",
68
+ " } else if (c === '?') {",
69
+ " out += '[^/]';",
70
+ " } else if ('.+^${}()|[]\\\\'.includes(c)) {",
71
+ ' out += `\\\\${c}`;',
72
+ ' } else {',
73
+ ' out += c;',
74
+ ' }',
75
+ ' }',
76
+ ' return new RegExp(`^${out}$`);',
77
+ '}',
78
+ '',
79
+ 'function matchesAny(relFile: string, globs: string[]): boolean {',
80
+ ' return globs.some((glob) => globToRegExp(glob).test(relFile));',
81
+ '}',
82
+ '',
83
+ 'function toRepoRelative(absPath: string): string {',
84
+ " return path.relative(REPO_ROOT, absPath).split(path.sep).join('/');",
85
+ '}',
86
+ '',
87
+ 'function walk(dir: string, acc: string[] = []): string[] {',
88
+ ' for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {',
89
+ ' if (IGNORED_DIRS.has(entry.name)) continue;',
90
+ ' const full = path.join(dir, entry.name);',
91
+ ' if (entry.isDirectory()) {',
92
+ ' walk(full, acc);',
93
+ " } else if (entry.isFile() && (entry.name.endsWith('.ts') || entry.name.endsWith('.tsx'))) {",
94
+ ' acc.push(full);',
95
+ ' }',
96
+ ' }',
97
+ ' return acc;',
98
+ '}',
99
+ '',
100
+ "const RELATIVE_IMPORT_RE = /(?:import|export)\\s+(?:[^'\";]*?\\bfrom\\s+)?['\"](\\.[^'\"]+)['\"]/g;",
101
+ '',
102
+ 'function findRelativeImports(source: string): string[] {',
103
+ ' const specs: string[] = [];',
104
+ ' RELATIVE_IMPORT_RE.lastIndex = 0;',
105
+ ' let match: RegExpExecArray | null;',
106
+ ' while ((match = RELATIVE_IMPORT_RE.exec(source))) {',
107
+ ' specs.push(match[1]);',
108
+ ' }',
109
+ ' return specs;',
110
+ '}',
111
+ '',
112
+ '// An import spec resolves to a module, not a specific file extension, so a',
113
+ '// forbid glob is checked against the bare resolved path plus its .ts/index.ts',
114
+ '// variants.',
115
+ 'function resolvedCandidates(fromFile: string, spec: string): string[] {',
116
+ ' const resolved = toRepoRelative(path.normalize(path.join(path.dirname(fromFile), spec)));',
117
+ ' return [resolved, `${resolved}.ts`, `${resolved}/index.ts`];',
118
+ '}',
119
+ '',
120
+ 'function evaluateForbiddenImport(rule: Rule): Violation[] {',
121
+ ' const { from, forbid } = rule.check;',
122
+ ' if (from.length === 0 || forbid.length === 0) return [];',
123
+ '',
124
+ ' const violations: Violation[] = [];',
125
+ ' for (const file of walk(REPO_ROOT)) {',
126
+ ' const relFile = toRepoRelative(file);',
127
+ ' if (!matchesAny(relFile, from)) continue;',
128
+ '',
129
+ " const source = fs.readFileSync(file, 'utf8');",
130
+ ' for (const spec of findRelativeImports(source)) {',
131
+ ' const candidates = resolvedCandidates(file, spec);',
132
+ ' if (candidates.some((candidate) => matchesAny(candidate, forbid))) {',
133
+ ' violations.push({',
134
+ ' ruleId: rule.id,',
135
+ ' severity: rule.severity,',
136
+ ' message: `${relFile} imports "${spec}", which resolves under a path forbidden by rule "${rule.id}"`,',
137
+ ' });',
138
+ ' }',
139
+ ' }',
140
+ ' }',
141
+ ' return violations;',
142
+ '}',
143
+ '',
144
+ 'function evaluateRule(rule: Rule): Violation[] {',
145
+ ' switch (rule.check.type) {',
146
+ " case 'forbidden-import':",
147
+ ' return evaluateForbiddenImport(rule);',
148
+ ' default:',
149
+ ' throw new Error(`architecture-rules: unknown check.type "${(rule.check as { type: string }).type}" on rule "${rule.id}"`);',
150
+ ' }',
151
+ '}',
152
+ '',
153
+ 'function main(): number {',
154
+ ' const rules = (rulesFile as { rules: Rule[] }).rules;',
155
+ ' let evaluated = 0;',
156
+ ' let deferred = 0;',
157
+ ' const violations: Violation[] = [];',
158
+ '',
159
+ ' for (const rule of rules) {',
160
+ ' if (!rule.enabled) {',
161
+ ' deferred++;',
162
+ ' console.log(`[deferred] ${rule.id}: ${rule.description}`);',
163
+ ' continue;',
164
+ ' }',
165
+ ' evaluated++;',
166
+ ' violations.push(...evaluateRule(rule));',
167
+ ' }',
168
+ '',
169
+ ' console.log(`\\narchitecture-rules: ${evaluated} rule(s) evaluated, ${deferred} deferred, ${violations.length} violation(s)`);',
170
+ ' for (const violation of violations) {',
171
+ ' console.error(` [${violation.severity}] ${violation.ruleId}: ${violation.message}`);',
172
+ ' }',
173
+ '',
174
+ ' return violations.length > 0 ? 1 : 0;',
175
+ '}',
176
+ '',
177
+ 'process.exit(main());',
178
+ ],
179
+ });
180
+ new projen_1.JsonFile(project, 'architecture-rules/tsconfig.json', {
181
+ marker: false,
182
+ obj: {
183
+ extends: '../tsconfig.json',
184
+ compilerOptions: {
185
+ noEmit: true,
186
+ rootDir: '.',
187
+ },
188
+ include: ['*.ts', '*.json'],
189
+ exclude: ['node_modules'],
190
+ },
191
+ });
192
+ new projen_1.TextFile(project, 'architecture-rules/README.md', {
193
+ marker: true,
194
+ lines: [
195
+ '# Architecture rules',
196
+ '',
197
+ 'A data-driven registry of architectural constraints, enforced by',
198
+ '`pnpm validate:architecture` and run as part of the pre-PR verification',
199
+ 'workflow (`workflows/workflow-pre-pr-verify.yaml`) before the swamp factory',
200
+ 'opens a PR. New rules are new entries in `rules.json`, not new code — the',
201
+ 'engine (`check.ts`) only needs a new case in `evaluateRule()` when a rule',
202
+ 'needs a genuinely new kind of check.',
203
+ '',
204
+ '## Rule shape',
205
+ '',
206
+ '```json',
207
+ '{',
208
+ ' "id": "unique-id",',
209
+ ' "description": "What this enforces and why.",',
210
+ ' "enabled": true,',
211
+ ' "severity": "low" | "medium" | "high" | "critical",',
212
+ ' "check": {',
213
+ ' "type": "forbidden-import",',
214
+ ' "from": ["glob patterns selecting files this rule inspects"],',
215
+ ' "forbid": ["glob patterns those files may not import from"]',
216
+ ' }',
217
+ '}',
218
+ '```',
219
+ '',
220
+ '`enabled: false` rules are skipped (reported as "deferred") rather than',
221
+ "evaluated — use this for a rule you've named and described but don't yet",
222
+ 'have a concrete convention to check.',
223
+ '',
224
+ '## Current rules',
225
+ '',
226
+ 'None yet — `rules.json` ships empty. Add rules as your domain module',
227
+ 'conventions solidify (e.g. an event-sourced/CQRS module layout under',
228
+ '`src/domains/<name>/{commands,events,aggregates,projections}/`).',
229
+ '',
230
+ '## Adding a check type',
231
+ '',
232
+ '`forbidden-import` is the only implemented `check.type`. If a future rule',
233
+ 'needs something it can\'t express (e.g. "every aggregate file must have a',
234
+ 'matching events file"), add a new `type` value, a matching interface, and a',
235
+ 'case in `evaluateRule()` in `check.ts` — keep the engine itself generic;',
236
+ 'rule-specific knowledge belongs in `rules.json`.',
237
+ ],
238
+ });
239
+ new projen_1.SampleFile(project, 'architecture-rules/rules.json', {
240
+ contents: JSON.stringify({ rules: [] }, null, 2) + '\n',
241
+ });
242
+ }
243
+ }
244
+ exports.SoftwareFactoryArchitectureRules = SoftwareFactoryArchitectureRules;
245
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU29mdHdhcmVGYWN0b3J5QXJjaGl0ZWN0dXJlUnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU29mdHdhcmVGYWN0b3J5QXJjaGl0ZWN0dXJlUnVsZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXdEO0FBR3hEOzs7OztHQUtHO0FBQ0gsTUFBYSxnQ0FBZ0M7SUFDM0MsWUFBWSxPQUFvQjtRQUM5QixJQUFJLGlCQUFRLENBQUMsT0FBTyxFQUFFLDZCQUE2QixFQUFFO1lBQ25ELE1BQU0sRUFBRSxJQUFJO1lBQ1osS0FBSyxFQUFFO2dCQUNMLEtBQUs7Z0JBQ0wsK0VBQStFO2dCQUMvRSw4RUFBOEU7Z0JBQzlFLGdGQUFnRjtnQkFDaEYsOEJBQThCO2dCQUM5QixLQUFLO2dCQUNMLGdDQUFnQztnQkFDaEMsb0NBQW9DO2dCQUNwQyx1Q0FBdUM7Z0JBQ3ZDLEVBQUU7Z0JBQ0Ysa0NBQWtDO2dCQUNsQyw2QkFBNkI7Z0JBQzdCLG9GQUFvRjtnQkFDcEYsbUJBQW1CO2dCQUNuQixtRkFBbUY7Z0JBQ25GLHFCQUFxQjtnQkFDckIsR0FBRztnQkFDSCxFQUFFO2dCQUNGLGtCQUFrQjtnQkFDbEIsZUFBZTtnQkFDZix3QkFBd0I7Z0JBQ3hCLHFCQUFxQjtnQkFDckIscURBQXFEO2dCQUNyRCxnQ0FBZ0M7Z0JBQ2hDLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRix1QkFBdUI7Z0JBQ3ZCLG1CQUFtQjtnQkFDbkIscUJBQXFCO2dCQUNyQixvQkFBb0I7Z0JBQ3BCLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRixrREFBa0Q7Z0JBQ2xELHNHQUFzRztnQkFDdEcsRUFBRTtnQkFDRixpRkFBaUY7Z0JBQ2pGLCtFQUErRTtnQkFDL0UsaUVBQWlFO2dCQUNqRSwrQ0FBK0M7Z0JBQy9DLGlCQUFpQjtnQkFDakIsMkNBQTJDO2dCQUMzQyx3QkFBd0I7Z0JBQ3hCLDZDQUE2QztnQkFDN0MsWUFBWTtnQkFDWixrQ0FBa0M7Z0JBQ2xDLDRC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QUMsT0FBTyxFQUFFLDhCQUE4QixFQUFFO1lBQ3BELE1BQU0sRUFBRSxJQUFJO1lBQ1osS0FBSyxFQUFFO2dCQUNMLHNCQUFzQjtnQkFDdEIsRUFBRTtnQkFDRixrRUFBa0U7Z0JBQ2xFLHlFQUF5RTtnQkFDekUsNkVBQTZFO2dCQUM3RSwyRUFBMkU7Z0JBQzNFLDJFQUEyRTtnQkFDM0Usc0NBQXNDO2dCQUN0QyxFQUFFO2dCQUNGLGVBQWU7Z0JBQ2YsRUFBRTtnQkFDRixTQUFTO2dCQUNULEdBQUc7Z0JBQ0gsc0JBQXNCO2dCQUN0QixpREFBaUQ7Z0JBQ2pELG9CQUFvQjtnQkFDcEIsdURBQXVEO2dCQUN2RCxjQUFjO2dCQUNkLGlDQUFpQztnQkFDakMsbUVBQW1FO2dCQUNuRSxpRUFBaUU7Z0JBQ2pFLEtBQUs7Z0JBQ0wsR0FBRztnQkFDSCxLQUFLO2dCQUNMLEVBQUU7Z0JBQ0YseUVBQXlFO2dCQUN6RSwwRUFBMEU7Z0JBQzFFLHNDQUFzQztnQkFDdEMsRUFBRTtnQkFDRixrQkFBa0I7Z0JBQ2xCLEVBQUU7Z0JBQ0Ysc0VBQXNFO2dCQUN0RSxzRUFBc0U7Z0JBQ3RFLGtFQUFrRTtnQkFDbEUsRUFBRTtnQkFDRix3QkFBd0I7Z0JBQ3hCLEVBQUU7Z0JBQ0YsMkVBQTJFO2dCQUMzRSwyRUFBMkU7Z0JBQzNFLDZFQUE2RTtnQkFDN0UsMEVBQTBFO2dCQUMxRSxrREFBa0Q7YUFDbkQ7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLG1CQUFVLENBQUMsT0FBTyxFQUFFLCtCQUErQixFQUFFO1lBQ3ZELFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJO1NBQ3hELENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQTNPRCw0RUEyT0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBKc29uRmlsZSwgU2FtcGxlRmlsZSwgVGV4dEZpbGUgfSBmcm9tICdwcm9qZW4nO1xuaW1wb3J0IHsgTm9kZVByb2plY3QgfSBmcm9tICdwcm9qZW4vbGliL2phdmFzY3JpcHQnO1xuXG4vKipcbiAqIFRoZSBnZW5lcmljLCBkYXRhLWRyaXZlbiBhcmNoaXRlY3R1cmUgcnVsZSBlbmdpbmUgcGx1cyBhbiBlbXB0eSBzZWVkXG4gKiBydWxlcy5qc29uLiBgY2hlY2sudHNgL2B0c2NvbmZpZy5qc29uYC9gUkVBRE1FLm1kYCBhcmUgbWFuYWdlZCAoQmF0bWFuXG4gKiBvd25zIHRoZSBlbmdpbmUpOyBgcnVsZXMuanNvbmAgaXMgYSBgU2FtcGxlRmlsZWAg4oCUIGVhY2ggcmVwbydzIG93biBydWxlc1xuICogYXJlIGRhdGEgdGhlIHRlYW0gb3ducywgbm90IHNvbWV0aGluZyBCYXRtYW4gc2hvdWxkIG92ZXJ3cml0ZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNvZnR3YXJlRmFjdG9yeUFyY2hpdGVjdHVyZVJ1bGVzIHtcbiAgY29uc3RydWN0b3IocHJvamVjdDogTm9kZVByb2plY3QpIHtcbiAgICBuZXcgVGV4dEZpbGUocHJvamVjdCwgJ2FyY2hpdGVjdHVyZS1ydWxlcy9jaGVjay50cycsIHtcbiAgICAgIG1hcmtlcjogdHJ1ZSxcbiAgICAgIGxpbmVzOiBbXG4gICAgICAgICcvKionLFxuICAgICAgICAnICogR2VuZXJpYyBhcmNoaXRlY3R1cmUtcnVsZSBlbmdpbmUuIFJ1bGVzIGxpdmUgZW50aXJlbHkgaW4gcnVsZXMuanNvbiDigJQgdGhpcycsXG4gICAgICAgICcgKiBmaWxlIG9ubHkga25vd3MgaG93IHRvIGV2YWx1YXRlIHRoZSBjaGVjayBcInR5cGVzXCIgdGhhdCBydWxlcyBjYW4gZGVjbGFyZS4nLFxuICAgICAgICAnICogQWRkIGEgbmV3IHJ1bGUgYnkgYWRkaW5nIGEgcnVsZXMuanNvbiBlbnRyeTsgYWRkIGEgbmV3IGNoZWNrIHR5cGUgYnkgYWRkaW5nJyxcbiAgICAgICAgJyAqIGEgY2FzZSBpbiBldmFsdWF0ZVJ1bGUoKS4nLFxuICAgICAgICAnICovJyxcbiAgICAgICAgXCJpbXBvcnQgKiBhcyBmcyBmcm9tICdub2RlOmZzJztcIixcbiAgICAgICAgXCJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XCIsXG4gICAgICAgIFwiaW1wb3J0IHJ1bGVzRmlsZSBmcm9tICcuL3J1bGVzLmpzb24nO1wiLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2ludGVyZmFjZSBGb3JiaWRkZW5JbXBvcnRDaGVjayB7JyxcbiAgICAgICAgXCIgIHR5cGU6ICdmb3JiaWRkZW4taW1wb3J0JztcIixcbiAgICAgICAgJyAgLy8gR2xvYiBwYXR0ZXJucyAocmVsYXRpdmUgdG8gcmVwbyByb290KSBzZWxlY3RpbmcgdGhlIGZpbGVzIHRoaXMgcnVsZSBpbnNwZWN0cy4nLFxuICAgICAgICAnICBmcm9tOiBzdHJpbmdbXTsnLFxuICAgICAgICAnICAvLyBHbG9iIHBhdHRlcm5zIChyZWxhdGl2ZSB0byByZXBvIHJvb3QpIHRoYXQgXCJmcm9tXCIgZmlsZXMgbWF5IG5vdCBpbXBvcnQgZnJvbS4nLFxuICAgICAgICAnICBmb3JiaWQ6IHN0cmluZ1tdOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdpbnRlcmZhY2UgUnVsZSB7JyxcbiAgICAgICAgJyAgaWQ6IHN0cmluZzsnLFxuICAgICAgICAnICBkZXNjcmlwdGlvbjogc3RyaW5nOycsXG4gICAgICAgICcgIGVuYWJsZWQ6IGJvb2xlYW47JyxcbiAgICAgICAgXCIgIHNldmVyaXR5OiAnbG93JyB8ICdtZWRpdW0nIHwgJ2hpZ2gnIHwgJ2NyaXRpY2FsJztcIixcbiAgICAgICAgJyAgY2hlY2s6IEZvcmJpZGRlbkltcG9ydENoZWNrOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdpbnRlcmZhY2UgVmlvbGF0aW9uIHsnLFxuICAgICAgICAnICBydWxlSWQ6IHN0cmluZzsnLFxuICAgICAgICAnICBzZXZlcml0eTogc3RyaW5nOycsXG4gICAgICAgICcgIG1lc3NhZ2U6IHN0cmluZzsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICBcImNvbnN0IFJFUE9fUk9PVCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLicpO1wiLFxuICAgICAgICBcImNvbnN0IElHTk9SRURfRElSUyA9IG5ldyBTZXQoWydub2RlX21vZHVsZXMnLCAnLmdpdCcsICcuc3dhbXAnLCAnY2RrLm91dCcsICdsaWInLCAnYnVpbGQnLCAnZGlzdCddKTtcIixcbiAgICAgICAgJycsXG4gICAgICAgICcvLyBNaW5pbWFsIGdsb2IgLT4gUmVnRXhwOiBzdXBwb3J0cyBcIipcIiwgXCIqKlwiLCBcIioqL1wiIGFuZCBsaXRlcmFsIHBhdGggc2VnbWVudHMuJyxcbiAgICAgICAgJy8vIE5vIG5ldyBkZXBlbmRlbmN5IGZvciB0aGlzIOKAlCB0aGUgb25seSBwYXR0ZXJuIHNoYXBlcyBydWxlcy5qc29uIGV2ZXIgbmVlZHMnLFxuICAgICAgICAnLy8gYXJlIGRpcmVjdG9yeS1wcmVmaXggZ2xvYnMgbGlrZSBcInNyYy9kb21haW5zLyovY29tbWFuZHMvKipcIi4nLFxuICAgICAgICAnZnVuY3Rpb24gZ2xvYlRvUmVnRXhwKGdsb2I6IHN0cmluZyk6IFJlZ0V4cCB7JyxcbiAgICAgICAgXCIgIGxldCBvdXQgPSAnJztcIixcbiAgICAgICAgJyAgZm9yIChsZXQgaSA9IDA7IGkgPCBnbG9iLmxlbmd0aDsgaSsrKSB7JyxcbiAgICAgICAgJyAgICBjb25zdCBjID0gZ2xvYltpXTsnLFxuICAgICAgICBcIiAgICBpZiAoYyA9PT0gJyonICYmIGdsb2JbaSArIDFdID09PSAnKicpIHtcIixcbiAgICAgICAgJyAgICAgIGkrKzsnLFxuICAgICAgICBcIiAgICAgIGlmIChnbG9iW2kgKyAxXSA9PT0gJy8nKSB7XCIsXG4gICAgICAgIFwiICAgICAgICBvdXQgKz0gJyg/Oi4qLyk/JztcIixcbiAgICAgICAgJyAgICAgICAgaSsrOycsXG4gICAgICAgICcgICAgICB9IGVsc2UgeycsXG4gICAgICAgIFwiICAgICAgICBvdXQgKz0gJy4qJztcIixcbiAgICAgICAgJyAgICAgIH0nLFxuICAgICAgICBcIiAgICB9IGVsc2UgaWYgKGMgPT09ICcqJykge1wiLFxuICAgICAgICBcIiAgICAgIG91dCArPSAnW14vXSonO1wiLFxuICAgICAgICBcIiAgICB9IGVsc2UgaWYgKGMgPT09ICc/Jykge1wiLFxuICAgICAgICBcIiAgICAgIG91dCArPSAnW14vXSc7XCIsXG4gICAgICAgIFwiICAgIH0gZWxzZSBpZiAoJy4rXiR7fSgpfFtdXFxcXFxcXFwnLmluY2x1ZGVzKGMpKSB7XCIsXG4gICAgICAgICcgICAgICBvdXQgKz0gYFxcXFxcXFxcJHtjfWA7JyxcbiAgICAgICAgJyAgICB9IGVsc2UgeycsXG4gICAgICAgICcgICAgICBvdXQgKz0gYzsnLFxuICAgICAgICAnICAgIH0nLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJyAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke291dH0kYCk7JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIG1hdGNoZXNBbnkocmVsRmlsZTogc3RyaW5nLCBnbG9iczogc3RyaW5nW10pOiBib29sZWFuIHsnLFxuICAgICAgICAnICByZXR1cm4gZ2xvYnMuc29tZSgoZ2xvYikgPT4gZ2xvYlRvUmVnRXhwKGdsb2IpLnRlc3QocmVsRmlsZSkpOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiB0b1JlcG9SZWxhdGl2ZShhYnNQYXRoOiBzdHJpbmcpOiBzdHJpbmcgeycsXG4gICAgICAgIFwiICByZXR1cm4gcGF0aC5yZWxhdGl2ZShSRVBPX1JPT1QsIGFic1BhdGgpLnNwbGl0KHBhdGguc2VwKS5qb2luKCcvJyk7XCIsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiB3YWxrKGRpcjogc3RyaW5nLCBhY2M6IHN0cmluZ1tdID0gW10pOiBzdHJpbmdbXSB7JyxcbiAgICAgICAgJyAgZm9yIChjb25zdCBlbnRyeSBvZiBmcy5yZWFkZGlyU3luYyhkaXIsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KSkgeycsXG4gICAgICAgICcgICAgaWYgKElHTk9SRURfRElSUy5oYXMoZW50cnkubmFtZSkpIGNvbnRpbnVlOycsXG4gICAgICAgICcgICAgY29uc3QgZnVsbCA9IHBhdGguam9pbihkaXIsIGVudHJ5Lm5hbWUpOycsXG4gICAgICAgICcgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHsnLFxuICAgICAgICAnICAgICAgd2FsayhmdWxsLCBhY2MpOycsXG4gICAgICAgIFwiICAgIH0gZWxzZSBpZiAoZW50cnkuaXNGaWxlKCkgJiYgKGVudHJ5Lm5hbWUuZW5kc1dpdGgoJy50cycpIHx8IGVudHJ5Lm5hbWUuZW5kc1dpdGgoJy50c3gnKSkpIHtcIixcbiAgICAgICAgJyAgICAgIGFjYy5wdXNoKGZ1bGwpOycsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnICByZXR1cm4gYWNjOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgIFwiY29uc3QgUkVMQVRJVkVfSU1QT1JUX1JFID0gLyg/OmltcG9ydHxleHBvcnQpXFxcXHMrKD86W14nXFxcIjtdKj9cXFxcYmZyb21cXFxccyspP1snXFxcIl0oXFxcXC5bXidcXFwiXSspWydcXFwiXS9nO1wiLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIGZpbmRSZWxhdGl2ZUltcG9ydHMoc291cmNlOiBzdHJpbmcpOiBzdHJpbmdbXSB7JyxcbiAgICAgICAgJyAgY29uc3Qgc3BlY3M6IHN0cmluZ1tdID0gW107JyxcbiAgICAgICAgJyAgUkVMQVRJVkVfSU1QT1JUX1JFLmxhc3RJbmRleCA9IDA7JyxcbiAgICAgICAgJyAgbGV0IG1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsOycsXG4gICAgICAgICcgIHdoaWxlICgobWF0Y2ggPSBSRUxBVElWRV9JTVBPUlRfUkUuZXhlYyhzb3VyY2UpKSkgeycsXG4gICAgICAgICcgICAgc3BlY3MucHVzaChtYXRjaFsxXSk7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcgIHJldHVybiBzcGVjczsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnLy8gQW4gaW1wb3J0IHNwZWMgcmVzb2x2ZXMgdG8gYSBtb2R1bGUsIG5vdCBhIHNwZWNpZmljIGZpbGUgZXh0ZW5zaW9uLCBzbyBhJyxcbiAgICAgICAgJy8vIGZvcmJpZCBnbG9iIGlzIGNoZWNrZWQgYWdhaW5zdCB0aGUgYmFyZSByZXNvbHZlZCBwYXRoIHBsdXMgaXRzIC50cy9pbmRleC50cycsXG4gICAgICAgICcvLyB2YXJpYW50cy4nLFxuICAgICAgICAnZnVuY3Rpb24gcmVzb2x2ZWRDYW5kaWRhdGVzKGZyb21GaWxlOiBzdHJpbmcsIHNwZWM6IHN0cmluZyk6IHN0cmluZ1tdIHsnLFxuICAgICAgICAnICBjb25zdCByZXNvbHZlZCA9IHRvUmVwb1JlbGF0aXZlKHBhdGgubm9ybWFsaXplKHBhdGguam9pbihwYXRoLmRpcm5hbWUoZnJvbUZpbGUpLCBzcGVjKSkpOycsXG4gICAgICAgICcgIHJldHVybiBbcmVzb2x2ZWQsIGAke3Jlc29sdmVkfS50c2AsIGAke3Jlc29sdmVkfS9pbmRleC50c2BdOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiBldmFsdWF0ZUZvcmJpZGRlbkltcG9ydChydWxlOiBSdWxlKTogVmlvbGF0aW9uW10geycsXG4gICAgICAgICcgIGNvbnN0IHsgZnJvbSwgZm9yYmlkIH0gPSBydWxlLmNoZWNrOycsXG4gICAgICAgICcgIGlmIChmcm9tLmxlbmd0aCA9PT0gMCB8fCBmb3JiaWQubGVuZ3RoID09PSAwKSByZXR1cm4gW107JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIGNvbnN0IHZpb2xhdGlvbnM6IFZpb2xhdGlvbltdID0gW107JyxcbiAgICAgICAgJyAgZm9yIChjb25zdCBmaWxlIG9mIHdhbGsoUkVQT19ST09UKSkgeycsXG4gICAgICAgICcgICAgY29uc3QgcmVsRmlsZSA9IHRvUmVwb1JlbGF0aXZlKGZpbGUpOycsXG4gICAgICAgICcgICAgaWYgKCFtYXRjaGVzQW55KHJlbEZpbGUsIGZyb20pKSBjb250aW51ZTsnLFxuICAgICAgICAnJyxcbiAgICAgICAgXCIgICAgY29uc3Qgc291cmNlID0gZnMucmVhZEZpbGVTeW5jKGZpbGUsICd1dGY4Jyk7XCIsXG4gICAgICAgICcgICAgZm9yIChjb25zdCBzcGVjIG9mIGZpbmRSZWxhdGl2ZUltcG9ydHMoc291cmNlKSkgeycsXG4gICAgICAgICcgICAgICBjb25zdCBjYW5kaWRhdGVzID0gcmVzb2x2ZWRDYW5kaWRhdGVzKGZpbGUsIHNwZWMpOycsXG4gICAgICAgICcgICAgICBpZiAoY2FuZGlkYXRlcy5zb21lKChjYW5kaWRhdGUpID0+IG1hdGNoZXNBbnkoY2FuZGlkYXRlLCBmb3JiaWQpKSkgeycsXG4gICAgICAgICcgICAgICAgIHZpb2xhdGlvbnMucHVzaCh7JyxcbiAgICAgICAgJyAgICAgICAgICBydWxlSWQ6IHJ1bGUuaWQsJyxcbiAgICAgICAgJyAgICAgICAgICBzZXZlcml0eTogcnVsZS5zZXZlcml0eSwnLFxuICAgICAgICAnICAgICAgICAgIG1lc3NhZ2U6IGAke3JlbEZpbGV9IGltcG9ydHMgXCIke3NwZWN9XCIsIHdoaWNoIHJlc29sdmVzIHVuZGVyIGEgcGF0aCBmb3JiaWRkZW4gYnkgcnVsZSBcIiR7cnVsZS5pZH1cImAsJyxcbiAgICAgICAgJyAgICAgICAgfSk7JyxcbiAgICAgICAgJyAgICAgIH0nLFxuICAgICAgICAnICAgIH0nLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJyAgcmV0dXJuIHZpb2xhdGlvbnM7JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIGV2YWx1YXRlUnVsZShydWxlOiBSdWxlKTogVmlvbGF0aW9uW10geycsXG4gICAgICAgICcgIHN3aXRjaCAocnVsZS5jaGVjay50eXBlKSB7JyxcbiAgICAgICAgXCIgICAgY2FzZSAnZm9yYmlkZGVuLWltcG9ydCc6XCIsXG4gICAgICAgICcgICAgICByZXR1cm4gZXZhbHVhdGVGb3JiaWRkZW5JbXBvcnQocnVsZSk7JyxcbiAgICAgICAgJyAgICBkZWZhdWx0OicsXG4gICAgICAgICcgICAgICB0aHJvdyBuZXcgRXJyb3IoYGFyY2hpdGVjdHVyZS1ydWxlczogdW5rbm93biBjaGVjay50eXBlIFwiJHsocnVsZS5jaGVjayBhcyB7IHR5cGU6IHN0cmluZyB9KS50eXBlfVwiIG9uIHJ1bGUgXCIke3J1bGUuaWR9XCJgKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIG1haW4oKTogbnVtYmVyIHsnLFxuICAgICAgICAnICBjb25zdCBydWxlcyA9IChydWxlc0ZpbGUgYXMgeyBydWxlczogUnVsZVtdIH0pLnJ1bGVzOycsXG4gICAgICAgICcgIGxldCBldmFsdWF0ZWQgPSAwOycsXG4gICAgICAgICcgIGxldCBkZWZlcnJlZCA9IDA7JyxcbiAgICAgICAgJyAgY29uc3QgdmlvbGF0aW9uczogVmlvbGF0aW9uW10gPSBbXTsnLFxuICAgICAgICAnJyxcbiAgICAgICAgJyAgZm9yIChjb25zdCBydWxlIG9mIHJ1bGVzKSB7JyxcbiAgICAgICAgJyAgICBpZiAoIXJ1bGUuZW5hYmxlZCkgeycsXG4gICAgICAgICcgICAgICBkZWZlcnJlZCsrOycsXG4gICAgICAgICcgICAgICBjb25zb2xlLmxvZyhgW2RlZmVycmVkXSAke3J1bGUuaWR9OiAke3J1bGUuZGVzY3JpcHRpb259YCk7JyxcbiAgICAgICAgJyAgICAgIGNvbnRpbnVlOycsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcgICAgZXZhbHVhdGVkKys7JyxcbiAgICAgICAgJyAgICB2aW9sYXRpb25zLnB1c2goLi4uZXZhbHVhdGVSdWxlKHJ1bGUpKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIGNvbnNvbGUubG9nKGBcXFxcbmFyY2hpdGVjdHVyZS1ydWxlczogJHtldmFsdWF0ZWR9IHJ1bGUocykgZXZhbHVhdGVkLCAke2RlZmVycmVkfSBkZWZlcnJlZCwgJHt2aW9sYXRpb25zLmxlbmd0aH0gdmlvbGF0aW9uKHMpYCk7JyxcbiAgICAgICAgJyAgZm9yIChjb25zdCB2aW9sYXRpb24gb2YgdmlvbGF0aW9ucykgeycsXG4gICAgICAgICcgICAgY29uc29sZS5lcnJvcihgICBbJHt2aW9sYXRpb24uc2V2ZXJpdHl9XSAke3Zpb2xhdGlvbi5ydWxlSWR9OiAke3Zpb2xhdGlvbi5tZXNzYWdlfWApOycsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnJyxcbiAgICAgICAgJyAgcmV0dXJuIHZpb2xhdGlvbnMubGVuZ3RoID4gMCA/IDEgOiAwOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdwcm9jZXNzLmV4aXQobWFpbigpKTsnLFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIG5ldyBKc29uRmlsZShwcm9qZWN0LCAnYXJjaGl0ZWN0dXJlLXJ1bGVzL3RzY29uZmlnLmpzb24nLCB7XG4gICAgICBtYXJrZXI6IGZhbHNlLFxuICAgICAgb2JqOiB7XG4gICAgICAgIGV4dGVuZHM6ICcuLi90c2NvbmZpZy5qc29uJyxcbiAgICAgICAgY29tcGlsZXJPcHRpb25zOiB7XG4gICAgICAgICAgbm9FbWl0OiB0cnVlLFxuICAgICAgICAgIHJvb3REaXI6ICcuJyxcbiAgICAgICAgfSxcbiAgICAgICAgaW5jbHVkZTogWycqLnRzJywgJyouanNvbiddLFxuICAgICAgICBleGNsdWRlOiBbJ25vZGVfbW9kdWxlcyddLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIG5ldyBUZXh0RmlsZShwcm9qZWN0LCAnYXJjaGl0ZWN0dXJlLXJ1bGVzL1JFQURNRS5tZCcsIHtcbiAgICAgIG1hcmtlcjogdHJ1ZSxcbiAgICAgIGxpbmVzOiBbXG4gICAgICAgICcjIEFyY2hpdGVjdHVyZSBydWxlcycsXG4gICAgICAgICcnLFxuICAgICAgICAnQSBkYXRhLWRyaXZlbiByZWdpc3RyeSBvZiBhcmNoaXRlY3R1cmFsIGNvbnN0cmFpbnRzLCBlbmZvcmNlZCBieScsXG4gICAgICAgICdgcG5wbSB2YWxpZGF0ZTphcmNoaXRlY3R1cmVgIGFuZCBydW4gYXMgcGFydCBvZiB0aGUgcHJlLVBSIHZlcmlmaWNhdGlvbicsXG4gICAgICAgICd3b3JrZmxvdyAoYHdvcmtmbG93cy93b3JrZmxvdy1wcmUtcHItdmVyaWZ5LnlhbWxgKSBiZWZvcmUgdGhlIHN3YW1wIGZhY3RvcnknLFxuICAgICAgICAnb3BlbnMgYSBQUi4gTmV3IHJ1bGVzIGFyZSBuZXcgZW50cmllcyBpbiBgcnVsZXMuanNvbmAsIG5vdCBuZXcgY29kZSDigJQgdGhlJyxcbiAgICAgICAgJ2VuZ2luZSAoYGNoZWNrLnRzYCkgb25seSBuZWVkcyBhIG5ldyBjYXNlIGluIGBldmFsdWF0ZVJ1bGUoKWAgd2hlbiBhIHJ1bGUnLFxuICAgICAgICAnbmVlZHMgYSBnZW51aW5lbHkgbmV3IGtpbmQgb2YgY2hlY2suJyxcbiAgICAgICAgJycsXG4gICAgICAgICcjIyBSdWxlIHNoYXBlJyxcbiAgICAgICAgJycsXG4gICAgICAgICdgYGBqc29uJyxcbiAgICAgICAgJ3snLFxuICAgICAgICAnICBcImlkXCI6IFwidW5pcXVlLWlkXCIsJyxcbiAgICAgICAgJyAgXCJkZXNjcmlwdGlvblwiOiBcIldoYXQgdGhpcyBlbmZvcmNlcyBhbmQgd2h5LlwiLCcsXG4gICAgICAgICcgIFwiZW5hYmxlZFwiOiB0cnVlLCcsXG4gICAgICAgICcgIFwic2V2ZXJpdHlcIjogXCJsb3dcIiB8IFwibWVkaXVtXCIgfCBcImhpZ2hcIiB8IFwiY3JpdGljYWxcIiwnLFxuICAgICAgICAnICBcImNoZWNrXCI6IHsnLFxuICAgICAgICAnICAgIFwidHlwZVwiOiBcImZvcmJpZGRlbi1pbXBvcnRcIiwnLFxuICAgICAgICAnICAgIFwiZnJvbVwiOiBbXCJnbG9iIHBhdHRlcm5zIHNlbGVjdGluZyBmaWxlcyB0aGlzIHJ1bGUgaW5zcGVjdHNcIl0sJyxcbiAgICAgICAgJyAgICBcImZvcmJpZFwiOiBbXCJnbG9iIHBhdHRlcm5zIHRob3NlIGZpbGVzIG1heSBub3QgaW1wb3J0IGZyb21cIl0nLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnYGBgJyxcbiAgICAgICAgJycsXG4gICAgICAgICdgZW5hYmxlZDogZmFsc2VgIHJ1bGVzIGFyZSBza2lwcGVkIChyZXBvcnRlZCBhcyBcImRlZmVycmVkXCIpIHJhdGhlciB0aGFuJyxcbiAgICAgICAgXCJldmFsdWF0ZWQg4oCUIHVzZSB0aGlzIGZvciBhIHJ1bGUgeW91J3ZlIG5hbWVkIGFuZCBkZXNjcmliZWQgYnV0IGRvbid0IHlldFwiLFxuICAgICAgICAnaGF2ZSBhIGNvbmNyZXRlIGNvbnZlbnRpb24gdG8gY2hlY2suJyxcbiAgICAgICAgJycsXG4gICAgICAgICcjIyBDdXJyZW50IHJ1bGVzJyxcbiAgICAgICAgJycsXG4gICAgICAgICdOb25lIHlldCDigJQgYHJ1bGVzLmpzb25gIHNoaXBzIGVtcHR5LiBBZGQgcnVsZXMgYXMgeW91ciBkb21haW4gbW9kdWxlJyxcbiAgICAgICAgJ2NvbnZlbnRpb25zIHNvbGlkaWZ5IChlLmcuIGFuIGV2ZW50LXNvdXJjZWQvQ1FSUyBtb2R1bGUgbGF5b3V0IHVuZGVyJyxcbiAgICAgICAgJ2BzcmMvZG9tYWlucy88bmFtZT4ve2NvbW1hbmRzLGV2ZW50cyxhZ2dyZWdhdGVzLHByb2plY3Rpb25zfS9gKS4nLFxuICAgICAgICAnJyxcbiAgICAgICAgJyMjIEFkZGluZyBhIGNoZWNrIHR5cGUnLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Bmb3JiaWRkZW4taW1wb3J0YCBpcyB0aGUgb25seSBpbXBsZW1lbnRlZCBgY2hlY2sudHlwZWAuIElmIGEgZnV0dXJlIHJ1bGUnLFxuICAgICAgICAnbmVlZHMgc29tZXRoaW5nIGl0IGNhblxcJ3QgZXhwcmVzcyAoZS5nLiBcImV2ZXJ5IGFnZ3JlZ2F0ZSBmaWxlIG11c3QgaGF2ZSBhJyxcbiAgICAgICAgJ21hdGNoaW5nIGV2ZW50cyBmaWxlXCIpLCBhZGQgYSBuZXcgYHR5cGVgIHZhbHVlLCBhIG1hdGNoaW5nIGludGVyZmFjZSwgYW5kIGEnLFxuICAgICAgICAnY2FzZSBpbiBgZXZhbHVhdGVSdWxlKClgIGluIGBjaGVjay50c2Ag4oCUIGtlZXAgdGhlIGVuZ2luZSBpdHNlbGYgZ2VuZXJpYzsnLFxuICAgICAgICAncnVsZS1zcGVjaWZpYyBrbm93bGVkZ2UgYmVsb25ncyBpbiBgcnVsZXMuanNvbmAuJyxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBuZXcgU2FtcGxlRmlsZShwcm9qZWN0LCAnYXJjaGl0ZWN0dXJlLXJ1bGVzL3J1bGVzLmpzb24nLCB7XG4gICAgICBjb250ZW50czogSlNPTi5zdHJpbmdpZnkoeyBydWxlczogW10gfSwgbnVsbCwgMikgKyAnXFxuJyxcbiAgICB9KTtcbiAgfVxufVxuIl19
@@ -0,0 +1,18 @@
1
+ import { NodeProject } from 'projen/lib/javascript';
2
+ export interface SoftwareFactoryAttestationOptions {
3
+ /**
4
+ * The bare repo name, used to point MANIFEST_FILES at
5
+ * `models/@swamp/software-factory/<repoName>-factory.yaml`.
6
+ */
7
+ readonly repoName: string;
8
+ }
9
+ /**
10
+ * The tamper-evident PR attestation mechanism: `manifest.ts` hashes the
11
+ * files that determine what pre-pr-verify checked, `verify.ts` re-checks
12
+ * those hashes (plus commit/status/freshness) against a PR's embedded
13
+ * `<!-- attestation-manifest -->` block at merge time. Fully generic engine
14
+ * logic — Batman owns and evolves these, so both are managed `TextFile`s.
15
+ */
16
+ export declare class SoftwareFactoryAttestation {
17
+ constructor(project: NodeProject, options: SoftwareFactoryAttestationOptions);
18
+ }