@devtrack-solution/codesdd 1.2.3 → 1.2.4

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 (213) hide show
  1. package/.sdd/skills/curated/devtrack-api/SKILL.md +98 -12
  2. package/.sdd/skills/curated/devtrack-api/agents/claude-code.yaml +10 -0
  3. package/.sdd/skills/curated/devtrack-api/agents/codex.yaml +10 -0
  4. package/.sdd/skills/curated/devtrack-api/agents/cursor.yaml +10 -0
  5. package/.sdd/skills/curated/devtrack-api/agents/gemini.yaml +10 -0
  6. package/.sdd/skills/curated/devtrack-api/agents/kimi.yaml +10 -0
  7. package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +5 -3
  8. package/.sdd/skills/curated/devtrack-api/agents/opencode.yaml +12 -0
  9. package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +61 -5
  10. package/.sdd/skills/curated/devtrack-api/references/consumer-sync-policy.md +15 -3
  11. package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +1951 -0
  12. package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +16 -14
  13. package/.sdd/skills/curated/devtrack-api/references/field-validation-protocol.md +40 -0
  14. package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +19 -2
  15. package/.sdd/skills/curated/devtrack-api/references/generated-artifact-invalidation.md +97 -0
  16. package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +30 -1
  17. package/.sdd/skills/curated/devtrack-api/references/portable-agent-contract.md +42 -0
  18. package/.sdd/skills/curated/devtrack-api/references/testing-validation.md +22 -1
  19. package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +9 -7
  20. package/README.md +280 -29
  21. package/dist/applications/sdd/index.d.ts +16 -0
  22. package/dist/applications/sdd/index.js +16 -0
  23. package/dist/cli/program.js +180 -11
  24. package/dist/commands/config.js +197 -10
  25. package/dist/commands/sdd/execution.js +408 -16
  26. package/dist/commands/sdd/plugin.js +5 -0
  27. package/dist/commands/sdd/shared.d.ts +1 -0
  28. package/dist/commands/sdd/shared.js +10 -0
  29. package/dist/commands/sdd.js +157 -7
  30. package/dist/core/cli/command-matrix.d.ts +18 -0
  31. package/dist/core/cli/command-matrix.js +157 -0
  32. package/dist/core/cli-command-quality.js +11 -0
  33. package/dist/core/completions/command-registry.js +45 -0
  34. package/dist/core/config-schema.d.ts +31 -1
  35. package/dist/core/config-schema.js +79 -5
  36. package/dist/core/config.d.ts +1 -0
  37. package/dist/core/config.js +11 -0
  38. package/dist/core/global-config.d.ts +29 -0
  39. package/dist/core/init.d.ts +2 -2
  40. package/dist/core/init.js +13 -14
  41. package/dist/core/sdd/agent-binding.d.ts +19 -19
  42. package/dist/core/sdd/agent-runtime-contract.d.ts +204 -0
  43. package/dist/core/sdd/agent-runtime-contract.js +200 -0
  44. package/dist/core/sdd/allocator-recovery.d.ts +14 -0
  45. package/dist/core/sdd/allocator-recovery.js +30 -0
  46. package/dist/core/sdd/allocator-security.d.ts +18 -0
  47. package/dist/core/sdd/allocator-security.js +36 -0
  48. package/dist/core/sdd/api-foundation-baseline.d.ts +111 -0
  49. package/dist/core/sdd/api-foundation-baseline.js +151 -0
  50. package/dist/core/sdd/api-foundation-parity.d.ts +114 -0
  51. package/dist/core/sdd/api-foundation-parity.js +131 -0
  52. package/dist/core/sdd/api-profile-catalog.d.ts +36 -0
  53. package/dist/core/sdd/api-profile-catalog.js +132 -0
  54. package/dist/core/sdd/api-profile-dry-run-projection.d.ts +93 -0
  55. package/dist/core/sdd/api-profile-dry-run-projection.js +370 -0
  56. package/dist/core/sdd/api-profile-recipes.d.ts +82 -0
  57. package/dist/core/sdd/api-profile-recipes.js +484 -0
  58. package/dist/core/sdd/artifact-id-allocator.d.ts +368 -0
  59. package/dist/core/sdd/artifact-id-allocator.js +510 -0
  60. package/dist/core/sdd/check.d.ts +52 -1
  61. package/dist/core/sdd/check.js +326 -11
  62. package/dist/core/sdd/coordination/coordination-adapters.d.ts +15 -8
  63. package/dist/core/sdd/coordination/coordination-adapters.js +43 -15
  64. package/dist/core/sdd/coordination/index.d.ts +1 -0
  65. package/dist/core/sdd/coordination/index.js +1 -0
  66. package/dist/core/sdd/coordination/redis-runtime.d.ts +131 -0
  67. package/dist/core/sdd/coordination/redis-runtime.js +698 -0
  68. package/dist/core/sdd/deepagent-contracts.d.ts +99 -5
  69. package/dist/core/sdd/deepagent-contracts.js +62 -0
  70. package/dist/core/sdd/deepagents/reversa-subagents.d.ts +3 -3
  71. package/dist/core/sdd/default-bootstrap-files.d.ts +2 -2
  72. package/dist/core/sdd/default-bootstrap-files.js +14 -10
  73. package/dist/core/sdd/default-skills.js +115 -9
  74. package/dist/core/sdd/devtrack-api-appliance.d.ts +42 -1
  75. package/dist/core/sdd/devtrack-api-appliance.js +159 -32
  76. package/dist/core/sdd/devtrack-api-architecture.d.ts +16 -0
  77. package/dist/core/sdd/devtrack-api-architecture.js +86 -0
  78. package/dist/core/sdd/docs-sync.js +24 -18
  79. package/dist/core/sdd/domain/capability-diff.d.ts +63 -0
  80. package/dist/core/sdd/domain/capability-diff.js +200 -0
  81. package/dist/core/sdd/domain/change-safety-guardrails.d.ts +74 -0
  82. package/dist/core/sdd/domain/change-safety-guardrails.js +333 -0
  83. package/dist/core/sdd/domain/semantic-intent-classifier.d.ts +29 -0
  84. package/dist/core/sdd/domain/semantic-intent-classifier.js +117 -0
  85. package/dist/core/sdd/enterprise-mutating-command-gate.d.ts +27 -0
  86. package/dist/core/sdd/enterprise-mutating-command-gate.js +104 -0
  87. package/dist/core/sdd/enterprise-provenance-gates.d.ts +20 -0
  88. package/dist/core/sdd/enterprise-provenance-gates.js +63 -0
  89. package/dist/core/sdd/enterprise-provisioning-policy.d.ts +26 -0
  90. package/dist/core/sdd/enterprise-provisioning-policy.js +104 -0
  91. package/dist/core/sdd/foundation-artifact-map-validator.d.ts +16 -0
  92. package/dist/core/sdd/foundation-artifact-map-validator.js +71 -0
  93. package/dist/core/sdd/foundation-layer-manifest.d.ts +24 -0
  94. package/dist/core/sdd/foundation-layer-manifest.js +117 -0
  95. package/dist/core/sdd/governance-schemas.d.ts +2 -2
  96. package/dist/core/sdd/governance-schemas.js +11 -2
  97. package/dist/core/sdd/intent-guard.d.ts +22 -0
  98. package/dist/core/sdd/intent-guard.js +67 -0
  99. package/dist/core/sdd/json-schema.js +13 -1
  100. package/dist/core/sdd/legacy-operations.js +169 -5
  101. package/dist/core/sdd/migrate-workspace.js +39 -0
  102. package/dist/core/sdd/package-security-gates.d.ts +21 -0
  103. package/dist/core/sdd/package-security-gates.js +121 -0
  104. package/dist/core/sdd/package-structure-gate.d.ts +85 -3
  105. package/dist/core/sdd/package-structure-gate.js +384 -11
  106. package/dist/core/sdd/parallel-feat-automation.d.ts +185 -7
  107. package/dist/core/sdd/parallel-feat-automation.js +212 -0
  108. package/dist/core/sdd/plugin-broker.d.ts +223 -4
  109. package/dist/core/sdd/plugin-broker.js +10 -0
  110. package/dist/core/sdd/plugin-cli.d.ts +30 -0
  111. package/dist/core/sdd/plugin-cli.js +70 -3
  112. package/dist/core/sdd/plugin-evidence.d.ts +73 -0
  113. package/dist/core/sdd/plugin-manifest.d.ts +69 -1
  114. package/dist/core/sdd/plugin-manifest.js +10 -0
  115. package/dist/core/sdd/plugin-policy-pack.d.ts +1 -1
  116. package/dist/core/sdd/plugin-policy.js +6 -1
  117. package/dist/core/sdd/plugin-registry.d.ts +138 -2
  118. package/dist/core/sdd/plugin-sdk-contract.d.ts +363 -0
  119. package/dist/core/sdd/plugin-sdk-contract.js +268 -0
  120. package/dist/core/sdd/plugin-skill-binding.d.ts +1 -1
  121. package/dist/core/sdd/quality-validation.d.ts +89 -16
  122. package/dist/core/sdd/release-readiness.d.ts +68 -0
  123. package/dist/core/sdd/release-readiness.js +767 -0
  124. package/dist/core/sdd/reversa-architecture-extractor.d.ts +13 -0
  125. package/dist/core/sdd/reversa-architecture-extractor.js +89 -0
  126. package/dist/core/sdd/reversa-artifact-writer.d.ts +18 -0
  127. package/dist/core/sdd/reversa-artifact-writer.js +40 -0
  128. package/dist/core/sdd/reversa-command-policy.d.ts +136 -0
  129. package/dist/core/sdd/reversa-command-policy.js +361 -0
  130. package/dist/core/sdd/reversa-data-extractor.d.ts +11 -0
  131. package/dist/core/sdd/reversa-data-extractor.js +73 -0
  132. package/dist/core/sdd/reversa-equivalence.d.ts +20 -0
  133. package/dist/core/sdd/reversa-equivalence.js +34 -0
  134. package/dist/core/sdd/reversa-evidence.d.ts +298 -0
  135. package/dist/core/sdd/reversa-evidence.js +118 -0
  136. package/dist/core/sdd/reversa-reconstruction.d.ts +29 -0
  137. package/dist/core/sdd/reversa-reconstruction.js +32 -0
  138. package/dist/core/sdd/reversa-rules-extractor.d.ts +12 -0
  139. package/dist/core/sdd/reversa-rules-extractor.js +86 -0
  140. package/dist/core/sdd/reversa-source-safety.d.ts +19 -0
  141. package/dist/core/sdd/reversa-source-safety.js +105 -0
  142. package/dist/core/sdd/reversa-surface-scout.d.ts +13 -0
  143. package/dist/core/sdd/reversa-surface-scout.js +85 -0
  144. package/dist/core/sdd/reversa-ux-mapper.d.ts +11 -0
  145. package/dist/core/sdd/reversa-ux-mapper.js +73 -0
  146. package/dist/core/sdd/runtime-boundary-contract.d.ts +45 -0
  147. package/dist/core/sdd/runtime-boundary-contract.js +90 -0
  148. package/dist/core/sdd/sdk-agent-plugin-quality-gates.d.ts +150 -0
  149. package/dist/core/sdd/sdk-agent-plugin-quality-gates.js +258 -0
  150. package/dist/core/sdd/services/agent-run.service.d.ts +38 -6
  151. package/dist/core/sdd/services/agent-run.service.js +73 -1
  152. package/dist/core/sdd/services/archive-quality-coherence.service.d.ts +17 -0
  153. package/dist/core/sdd/services/archive-quality-coherence.service.js +141 -0
  154. package/dist/core/sdd/services/capability-diff.service.d.ts +18 -0
  155. package/dist/core/sdd/services/capability-diff.service.js +26 -0
  156. package/dist/core/sdd/services/change-safety-preflight.service.d.ts +17 -0
  157. package/dist/core/sdd/services/change-safety-preflight.service.js +17 -0
  158. package/dist/core/sdd/services/context.service.d.ts +43 -340
  159. package/dist/core/sdd/services/context.service.js +323 -9
  160. package/dist/core/sdd/services/decide.service.js +1 -1
  161. package/dist/core/sdd/services/finalize.service.d.ts +27 -0
  162. package/dist/core/sdd/services/finalize.service.js +226 -18
  163. package/dist/core/sdd/services/frontend-impact.service.d.ts +1 -1
  164. package/dist/core/sdd/services/historical-quality-regression.service.d.ts +35 -0
  165. package/dist/core/sdd/services/historical-quality-regression.service.js +228 -0
  166. package/dist/core/sdd/services/ingest-deposito.service.js +1 -1
  167. package/dist/core/sdd/services/planning-execution-coherence.service.d.ts +45 -0
  168. package/dist/core/sdd/services/planning-execution-coherence.service.js +225 -0
  169. package/dist/core/sdd/services/semantic-intent-classifier.service.d.ts +6 -0
  170. package/dist/core/sdd/services/semantic-intent-classifier.service.js +7 -0
  171. package/dist/core/sdd/state.d.ts +1 -0
  172. package/dist/core/sdd/state.js +266 -34
  173. package/dist/core/sdd/store/sdd-stores.js +2 -2
  174. package/dist/core/sdd/structural-health.d.ts +13 -13
  175. package/dist/core/sdd/types.d.ts +30 -15
  176. package/dist/core/sdd/types.js +4 -0
  177. package/dist/core/sdd/views.js +17 -0
  178. package/dist/core/sdd/workspace-schemas.d.ts +428 -7
  179. package/dist/core/sdd/workspace-schemas.js +223 -70
  180. package/dist/core/shared/skill-generation.d.ts +2 -0
  181. package/dist/core/shared/skill-generation.js +19 -2
  182. package/dist/core/shared/tool-detection.d.ts +19 -0
  183. package/dist/core/shared/tool-detection.js +89 -0
  184. package/dist/domains/sdd/index.d.ts +6 -0
  185. package/dist/domains/sdd/index.js +6 -0
  186. package/dist/infrastructures/sdd/index.d.ts +7 -0
  187. package/dist/infrastructures/sdd/index.js +6 -0
  188. package/dist/presentations/cli/sdd/index.d.ts +3 -0
  189. package/dist/presentations/cli/sdd/index.js +3 -0
  190. package/dist/shared/sdd/index.d.ts +3 -0
  191. package/dist/shared/sdd/index.js +2 -0
  192. package/package.json +14 -10
  193. package/schemas/sdd/2-plan.schema.json +207 -2
  194. package/schemas/sdd/5-quality.schema.json +324 -25
  195. package/schemas/sdd/agent-runtime-command-plan.schema.json +212 -0
  196. package/schemas/sdd/agent-runtime-opencode-run-evidence.schema.json +270 -0
  197. package/schemas/sdd/codesdd-plugin.schema.json +171 -0
  198. package/schemas/sdd/deepagent-run-request.schema.json +316 -0
  199. package/schemas/sdd/parallel-feat-automation-plan.schema.json +89 -0
  200. package/schemas/sdd/parallel-feat-scheduler-request.schema.json +116 -0
  201. package/schemas/sdd/parallel-feat-scheduler-result.schema.json +404 -0
  202. package/schemas/sdd/plugin-artifact-manifest.schema.json +109 -0
  203. package/schemas/sdd/plugin-artifact-map.schema.json +223 -0
  204. package/schemas/sdd/plugin-evidence-manifest.schema.json +109 -0
  205. package/schemas/sdd/plugin-language-runtime.schema.json +103 -0
  206. package/schemas/sdd/plugin-package-governance.schema.json +74 -0
  207. package/schemas/sdd/plugin-registry.schema.json +171 -0
  208. package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +109 -0
  209. package/schemas/sdd/quality-evidence-bundle.schema.json +109 -0
  210. package/schemas/sdd/reversa-evidence-bundle.schema.json +466 -0
  211. package/schemas/sdd/sdk-agent-plugin-quality-gate-input.schema.json +168 -0
  212. package/schemas/sdd/sdk-agent-plugin-quality-gate-report.schema.json +160 -0
  213. package/schemas/sdd/workspace-catalog.schema.json +5298 -1409
@@ -0,0 +1,86 @@
1
+ import { attestReversaSource } from './reversa-source-safety.js';
2
+ export function buildReversaRulesInventory(input) {
3
+ const accepted = input.sources
4
+ .map((source) => ({ source, attestation: attestReversaSource({ sourcePath: source.path, content: source.content }) }))
5
+ .filter((entry) => entry.attestation.status === 'accepted' && entry.attestation.attestation);
6
+ const blockedCount = input.sources.length - accepted.length;
7
+ const rules = accepted.flatMap(({ source, attestation }) => scanRules(attestation.normalized_path, source.content));
8
+ const workflows = accepted.flatMap(({ source, attestation }) => scanWorkflows(attestation.normalized_path, source.content));
9
+ const findings = [];
10
+ if (rules.length > 0) {
11
+ findings.push({
12
+ id: 'REV-FIND-RULES-INVARIANTS',
13
+ phase: 'rules',
14
+ title: 'Business rules and invariants',
15
+ summary: `Detected ${rules.length} rule, validation or invariant candidates.`,
16
+ confidence: 'medium',
17
+ source_refs: unique(rules.map((entry) => entry.source_ref)),
18
+ contradiction_refs: [],
19
+ promoted_refs: [],
20
+ metadata: { rules },
21
+ });
22
+ }
23
+ if (workflows.length > 0) {
24
+ findings.push({
25
+ id: 'REV-FIND-RULES-WORKFLOWS',
26
+ phase: 'rules',
27
+ title: 'Workflow transitions',
28
+ summary: `Detected ${workflows.length} workflow or state transition candidates.`,
29
+ confidence: 'medium',
30
+ source_refs: unique(workflows.map((entry) => entry.source_ref)),
31
+ contradiction_refs: [],
32
+ promoted_refs: [],
33
+ metadata: { workflows },
34
+ });
35
+ }
36
+ return {
37
+ schema_version: 1,
38
+ contract: 'reversa-evidence-bundle/v1',
39
+ operation_id: input.operationId,
40
+ generated_at: input.generatedAt,
41
+ feature_ref: input.featureRef,
42
+ mode: 'read-only',
43
+ source_attestations: accepted.map((entry) => entry.attestation.attestation),
44
+ findings,
45
+ artifacts: [{
46
+ path: `.sdd/evidence/reversa/${input.featureRef}/business-rules.yaml`,
47
+ artifact_type: 'business_rules',
48
+ phase: 'rules',
49
+ produced_by: 'codesdd reversa rules extractor',
50
+ write_scope: 'read_only',
51
+ }],
52
+ validations: [{
53
+ id: 'REV-VAL-RULES-SAFETY',
54
+ phase: 'rules',
55
+ command: 'buildReversaRulesInventory',
56
+ status: blockedCount === 0 ? 'passed' : 'blocked',
57
+ issue_codes: blockedCount === 0 ? [] : ['UNSAFE_SOURCE_BLOCKED'],
58
+ }],
59
+ contradictions: [],
60
+ human_questions: rules.length === 0 ? [{
61
+ id: 'REV-Q-RULES-MISSING',
62
+ question: 'No explicit business rules were detected. Which workflows or invariants should be reviewed manually?',
63
+ blocks_phase: 'artifact_generation',
64
+ required_before_apply: true,
65
+ }] : [],
66
+ quality_refs: [`.sdd/active/${input.featureRef}/5-quality.yaml`],
67
+ residual_risks: [],
68
+ metadata: { rule_count: rules.length, workflow_count: workflows.length },
69
+ };
70
+ }
71
+ function scanRules(sourceRef, content) {
72
+ return [...content.matchAll(/\b(?:if|validate|ensure|invariant|policy|rule|throw new)\b[^\n;]*/giu)].map((match) => ({
73
+ expression: match[0].trim(),
74
+ source_ref: sourceRef,
75
+ }));
76
+ }
77
+ function scanWorkflows(sourceRef, content) {
78
+ return [...content.matchAll(/\b(?:status|state|stage)\s*=\s*['"]?([A-Za-z0-9_-]+)['"]?/giu)].map((match) => ({
79
+ state: match[1] ?? 'unknown',
80
+ source_ref: sourceRef,
81
+ }));
82
+ }
83
+ function unique(values) {
84
+ return [...new Set(values)];
85
+ }
86
+ //# sourceMappingURL=reversa-rules-extractor.js.map
@@ -0,0 +1,19 @@
1
+ import { type ReversaSourceAttestation } from './reversa-evidence.js';
2
+ export interface ReversaSourceIntakeInput {
3
+ sourcePath: string;
4
+ sourceType?: ReversaSourceAttestation['source_type'];
5
+ content?: string;
6
+ trustLevel?: ReversaSourceAttestation['trust_level'];
7
+ }
8
+ export interface ReversaSourceIntakeResult {
9
+ status: 'accepted' | 'blocked';
10
+ normalized_path: string | null;
11
+ reason: string | null;
12
+ attestation: ReversaSourceAttestation | null;
13
+ redacted_content?: string;
14
+ }
15
+ export declare function attestReversaSource(input: ReversaSourceIntakeInput): ReversaSourceIntakeResult;
16
+ export declare function normalizeReversaSourcePath(value: string): string | null;
17
+ export declare function redactReversaSensitiveText(value: string): string;
18
+ export declare function isReversaCanonicalStatePath(value: string): boolean;
19
+ //# sourceMappingURL=reversa-source-safety.d.ts.map
@@ -0,0 +1,105 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { reversaSourceAttestationSchema } from './reversa-evidence.js';
3
+ const WINDOWS_ABSOLUTE_PATH_PATTERN = /^[A-Za-z]:[\\/]/;
4
+ const SECRET_PATH_SEGMENTS = new Set([
5
+ '.aws',
6
+ '.env',
7
+ '.ssh',
8
+ 'credential',
9
+ 'credentials',
10
+ 'id_rsa',
11
+ 'pem',
12
+ 'private',
13
+ 'secret',
14
+ 'secrets',
15
+ 'token',
16
+ ]);
17
+ const SENSITIVE_KEY_TOKENS = ['key', 'secret', 'token', 'password', 'credential', 'private', 'auth'];
18
+ export function attestReversaSource(input) {
19
+ const normalizedPath = normalizeReversaSourcePath(input.sourcePath);
20
+ if (!normalizedPath) {
21
+ return blocked(input.sourcePath, 'Source path must be project-relative and must not contain traversal or absolute roots.');
22
+ }
23
+ if (isCanonicalStatePath(normalizedPath)) {
24
+ return blocked(normalizedPath, 'Reversa inputs cannot target canonical CodeSDD state under .sdd/state/.');
25
+ }
26
+ if (hasSecretPathSegment(normalizedPath)) {
27
+ return blocked(normalizedPath, 'Source path is blocked by Reversa secret-path policy.');
28
+ }
29
+ const redactedContent = typeof input.content === 'string' ? redactReversaSensitiveText(input.content) : undefined;
30
+ const redactionStatus = typeof input.content === 'string' && redactedContent !== input.content ? 'redacted' : 'not_required';
31
+ const attestation = reversaSourceAttestationSchema.parse({
32
+ source_ref: normalizedPath,
33
+ source_type: input.sourceType ?? inferSourceType(normalizedPath),
34
+ trust_level: input.trustLevel ?? 'hostile',
35
+ sha256: input.content ? createHash('sha256').update(redactedContent ?? input.content).digest('hex') : undefined,
36
+ redaction_status: redactionStatus,
37
+ });
38
+ return {
39
+ status: 'accepted',
40
+ normalized_path: normalizedPath,
41
+ reason: null,
42
+ attestation,
43
+ redacted_content: redactedContent,
44
+ };
45
+ }
46
+ export function normalizeReversaSourcePath(value) {
47
+ const normalized = value.trim().replace(/\\/gu, '/').replace(/^\.\//u, '');
48
+ if (!normalized || normalized === '.' || normalized.startsWith('/') || WINDOWS_ABSOLUTE_PATH_PATTERN.test(normalized)) {
49
+ return null;
50
+ }
51
+ const segments = normalized.split('/').filter(Boolean);
52
+ if (segments.some((segment) => segment === '..')) {
53
+ return null;
54
+ }
55
+ return segments.join('/');
56
+ }
57
+ export function redactReversaSensitiveText(value) {
58
+ return value
59
+ .split(/\r?\n/u)
60
+ .map((line) => {
61
+ const keyMatch = line.match(/^(\s*["']?([A-Za-z0-9_.-]+)["']?\s*[:=]\s*)(.+)$/u);
62
+ if (!keyMatch) {
63
+ return line.replace(/(bearer\s+)[A-Za-z0-9._~+/-]+=*/giu, '$1[REDACTED]');
64
+ }
65
+ const key = keyMatch[2] ?? '';
66
+ if (!SENSITIVE_KEY_TOKENS.some((token) => key.toLowerCase().includes(token))) {
67
+ return line;
68
+ }
69
+ return `${keyMatch[1]}[REDACTED]`;
70
+ })
71
+ .join('\n');
72
+ }
73
+ export function isReversaCanonicalStatePath(value) {
74
+ const normalized = normalizeReversaSourcePath(value);
75
+ return normalized ? isCanonicalStatePath(normalized) : false;
76
+ }
77
+ function blocked(sourcePath, reason) {
78
+ return {
79
+ status: 'blocked',
80
+ normalized_path: normalizeReversaSourcePath(sourcePath),
81
+ reason,
82
+ attestation: null,
83
+ };
84
+ }
85
+ function isCanonicalStatePath(value) {
86
+ return value === '.sdd/state' || value.startsWith('.sdd/state/');
87
+ }
88
+ function hasSecretPathSegment(value) {
89
+ return value
90
+ .toLowerCase()
91
+ .split('/')
92
+ .some((segment) => SECRET_PATH_SEGMENTS.has(segment) || segment.endsWith('.pem'));
93
+ }
94
+ function inferSourceType(path) {
95
+ if (/\.(md|mdx|txt|rst)$/iu.test(path))
96
+ return 'document';
97
+ if (/\.(ya?ml|json|toml|ini|env)$/iu.test(path))
98
+ return 'config';
99
+ if (/\.(log|out)$/iu.test(path))
100
+ return 'runtime_log';
101
+ if (/\.(sql|prisma)$/iu.test(path))
102
+ return 'database_schema';
103
+ return 'repository';
104
+ }
105
+ //# sourceMappingURL=reversa-source-safety.js.map
@@ -0,0 +1,13 @@
1
+ import type { ReversaEvidenceBundle } from './reversa-evidence.js';
2
+ export interface ReversaSurfaceSource {
3
+ path: string;
4
+ content: string;
5
+ }
6
+ export interface BuildReversaSurfaceInventoryInput {
7
+ featureRef: string;
8
+ operationId: string;
9
+ generatedAt: string;
10
+ sources: ReversaSurfaceSource[];
11
+ }
12
+ export declare function buildReversaSurfaceInventory(input: BuildReversaSurfaceInventoryInput): ReversaEvidenceBundle;
13
+ //# sourceMappingURL=reversa-surface-scout.d.ts.map
@@ -0,0 +1,85 @@
1
+ import { attestReversaSource } from './reversa-source-safety.js';
2
+ export function buildReversaSurfaceInventory(input) {
3
+ const attestations = input.sources.map((source) => attestReversaSource({
4
+ sourcePath: source.path,
5
+ content: source.content,
6
+ }));
7
+ const accepted = attestations.filter((entry) => entry.status === 'accepted' && entry.attestation);
8
+ const blocked = attestations.filter((entry) => entry.status === 'blocked');
9
+ const findings = accepted.flatMap((entry) => {
10
+ const source = input.sources.find((candidate) => entry.normalized_path === candidate.path.replace(/^\.\//u, ''));
11
+ return source ? scanSurface(entry.normalized_path, source.content) : [];
12
+ });
13
+ return {
14
+ schema_version: 1,
15
+ contract: 'reversa-evidence-bundle/v1',
16
+ operation_id: input.operationId,
17
+ generated_at: input.generatedAt,
18
+ feature_ref: input.featureRef,
19
+ mode: 'read-only',
20
+ source_attestations: accepted.map((entry) => entry.attestation),
21
+ findings,
22
+ artifacts: [
23
+ {
24
+ path: `.sdd/evidence/reversa/${input.featureRef}/surface-inventory.yaml`,
25
+ artifact_type: 'inventory',
26
+ phase: 'surface',
27
+ produced_by: 'codesdd reversa surface scout',
28
+ write_scope: 'read_only',
29
+ },
30
+ ],
31
+ validations: [
32
+ {
33
+ id: 'REV-VAL-SURFACE-SAFETY',
34
+ phase: 'surface',
35
+ command: 'buildReversaSurfaceInventory',
36
+ status: blocked.length === 0 ? 'passed' : 'blocked',
37
+ issue_codes: blocked.length === 0 ? [] : ['UNSAFE_SOURCE_BLOCKED'],
38
+ },
39
+ ],
40
+ contradictions: [],
41
+ human_questions: [],
42
+ quality_refs: [`.sdd/active/${input.featureRef}/5-quality.yaml`],
43
+ residual_risks: blocked.map((entry) => ({
44
+ code: 'UNSAFE_SOURCE_BLOCKED',
45
+ severity: 'medium',
46
+ description: entry.reason ?? 'A legacy source was blocked by Reversa intake safety.',
47
+ mitigation: 'Review source path and provide a safe project-relative source before extraction.',
48
+ })),
49
+ metadata: {
50
+ counts: summarizeSurface(findings),
51
+ },
52
+ };
53
+ }
54
+ function scanSurface(sourceRef, content) {
55
+ const findings = [];
56
+ const routeMatches = [...content.matchAll(/\b(?:app|router)\.(get|post|put|patch|delete)\s*\(\s*['"`]([^'"`]+)['"`]/giu)];
57
+ const controllerMatches = [...content.matchAll(/@(Controller|Get|Post|Put|Patch|Delete)\s*\(\s*['"`]?([^'"`)]*)['"`]?\s*\)/giu)];
58
+ const jobMatches = [...content.matchAll(/\b(?:cron|schedule|job|queue|worker)\b/giu)];
59
+ const commandMatches = [...content.matchAll(/\b(?:command|program\.command|Command)\b/gu)];
60
+ const screenMatches = [...content.matchAll(/(?:component|screen|page|route)/giu)];
61
+ pushFinding(findings, 'API', 'API endpoints', routeMatches.length + controllerMatches.length, sourceRef);
62
+ pushFinding(findings, 'JOB', 'Jobs and workers', jobMatches.length, sourceRef);
63
+ pushFinding(findings, 'COMMAND', 'CLI commands', commandMatches.length, sourceRef);
64
+ pushFinding(findings, 'SCREEN', 'Screens and routes', screenMatches.length, sourceRef);
65
+ return findings;
66
+ }
67
+ function pushFinding(findings, suffix, title, count, sourceRef) {
68
+ if (count === 0)
69
+ return;
70
+ findings.push({
71
+ id: `REV-FIND-SURFACE-${suffix}`,
72
+ phase: 'surface',
73
+ title,
74
+ summary: `${title} detected in ${sourceRef}: ${count}.`,
75
+ confidence: 'medium',
76
+ source_refs: [sourceRef],
77
+ contradiction_refs: [],
78
+ promoted_refs: [],
79
+ metadata: { count },
80
+ });
81
+ }
82
+ function summarizeSurface(findings) {
83
+ return Object.fromEntries(findings.map((finding) => [finding.id, Number(finding.metadata.count ?? 0)]));
84
+ }
85
+ //# sourceMappingURL=reversa-surface-scout.js.map
@@ -0,0 +1,11 @@
1
+ import type { ReversaEvidenceBundle } from './reversa-evidence.js';
2
+ export declare function buildReversaUxPermissionMap(input: {
3
+ featureRef: string;
4
+ operationId: string;
5
+ generatedAt: string;
6
+ sources: Array<{
7
+ path: string;
8
+ content: string;
9
+ }>;
10
+ }): ReversaEvidenceBundle;
11
+ //# sourceMappingURL=reversa-ux-mapper.d.ts.map
@@ -0,0 +1,73 @@
1
+ import { attestReversaSource } from './reversa-source-safety.js';
2
+ export function buildReversaUxPermissionMap(input) {
3
+ const accepted = input.sources
4
+ .map((source) => ({ source, attestation: attestReversaSource({ sourcePath: source.path, content: source.content }) }))
5
+ .filter((entry) => entry.attestation.status === 'accepted' && entry.attestation.attestation);
6
+ const screens = accepted.flatMap(({ source, attestation }) => scanScreens(attestation.normalized_path, source.content));
7
+ const permissions = accepted.flatMap(({ source, attestation }) => scanPermissions(attestation.normalized_path, source.content));
8
+ const findings = [];
9
+ if (screens.length > 0) {
10
+ findings.push({
11
+ id: 'REV-FIND-UX-SCREENS',
12
+ phase: 'ux',
13
+ title: 'Screens and UI routes',
14
+ summary: `Detected ${screens.length} screen, component or route candidates.`,
15
+ confidence: 'medium',
16
+ source_refs: [...new Set(screens.map((entry) => entry.source_ref))],
17
+ contradiction_refs: [],
18
+ promoted_refs: [],
19
+ metadata: { screens },
20
+ });
21
+ }
22
+ if (permissions.length > 0) {
23
+ findings.push({
24
+ id: 'REV-FIND-UX-PERMISSIONS',
25
+ phase: 'ux',
26
+ title: 'Permission and guard flows',
27
+ summary: `Detected ${permissions.length} permission or guard candidates.`,
28
+ confidence: 'medium',
29
+ source_refs: [...new Set(permissions.map((entry) => entry.source_ref))],
30
+ contradiction_refs: [],
31
+ promoted_refs: [],
32
+ metadata: { permissions },
33
+ });
34
+ }
35
+ return {
36
+ schema_version: 1,
37
+ contract: 'reversa-evidence-bundle/v1',
38
+ operation_id: input.operationId,
39
+ generated_at: input.generatedAt,
40
+ feature_ref: input.featureRef,
41
+ mode: 'read-only',
42
+ source_attestations: accepted.map((entry) => entry.attestation.attestation),
43
+ findings,
44
+ artifacts: [{
45
+ path: `.sdd/evidence/reversa/${input.featureRef}/ux-permission-map.yaml`,
46
+ artifact_type: 'ux_map',
47
+ phase: 'ux',
48
+ produced_by: 'codesdd reversa ux mapper',
49
+ write_scope: 'read_only',
50
+ }],
51
+ validations: [{
52
+ id: 'REV-VAL-UX-SAFETY',
53
+ phase: 'ux',
54
+ command: 'buildReversaUxPermissionMap',
55
+ status: accepted.length === input.sources.length ? 'passed' : 'blocked',
56
+ issue_codes: accepted.length === input.sources.length ? [] : ['UNSAFE_SOURCE_BLOCKED'],
57
+ }],
58
+ contradictions: [],
59
+ human_questions: [],
60
+ quality_refs: [`.sdd/active/${input.featureRef}/5-quality.yaml`],
61
+ residual_risks: [],
62
+ metadata: { screen_count: screens.length, permission_count: permissions.length },
63
+ };
64
+ }
65
+ function scanScreens(sourceRef, content) {
66
+ return [...content.matchAll(/\b(?:component|screen|page|route|path)\b\s*[:=]?\s*['"]?([A-Za-z0-9_/-]*)/giu)]
67
+ .map((match) => ({ name: match[1] || match[0], source_ref: sourceRef }));
68
+ }
69
+ function scanPermissions(sourceRef, content) {
70
+ return [...content.matchAll(/\b(?:guard|canActivate|permission|role|rbac|auth)\b/giu)]
71
+ .map((match) => ({ signal: match[0].toLowerCase(), source_ref: sourceRef }));
72
+ }
73
+ //# sourceMappingURL=reversa-ux-mapper.js.map
@@ -0,0 +1,45 @@
1
+ export declare const PROJECT_STATE_DIR_NAME = ".sdd";
2
+ export declare const FORBIDDEN_PROJECT_RUNTIME_DIR_NAME = ".codesdd";
3
+ export type CodesddStorageBoundary = 'project-state' | 'global-config' | 'global-cache' | 'global-runtime' | 'legacy-read-fallback' | 'invalid-project-runtime' | 'external';
4
+ export interface CodesddStorageBoundaryClassification {
5
+ boundary: CodesddStorageBoundary;
6
+ path: string;
7
+ valid: boolean;
8
+ canonical: boolean;
9
+ versioned: boolean;
10
+ cacheable: boolean;
11
+ reason: string;
12
+ }
13
+ export interface CodesddStorageBoundaryReport {
14
+ schema_version: 1;
15
+ project_root: string;
16
+ project_state_dir: string;
17
+ global_runtime_dir: string;
18
+ global_config_path: string;
19
+ global_cache_dir: string;
20
+ global_cache_tiers: Record<string, string>;
21
+ legacy_config_path: string;
22
+ rules: {
23
+ versioned_project_state: string;
24
+ global_runtime: string;
25
+ global_cache: string;
26
+ forbidden_project_runtime: string;
27
+ };
28
+ }
29
+ export interface CodesddStorageBoundaryValidation {
30
+ valid: boolean;
31
+ findings: Array<{
32
+ path: string;
33
+ boundary: CodesddStorageBoundary;
34
+ message: string;
35
+ }>;
36
+ classifications: CodesddStorageBoundaryClassification[];
37
+ }
38
+ export declare function buildCodesddStorageBoundaryReport(projectRoot?: string): CodesddStorageBoundaryReport;
39
+ export declare function classifyCodesddStoragePath(targetPath: string, options?: {
40
+ projectRoot?: string;
41
+ }): CodesddStorageBoundaryClassification;
42
+ export declare function validateCodesddStoragePaths(targetPaths: string[], options?: {
43
+ projectRoot?: string;
44
+ }): CodesddStorageBoundaryValidation;
45
+ //# sourceMappingURL=runtime-boundary-contract.d.ts.map
@@ -0,0 +1,90 @@
1
+ import * as path from 'node:path';
2
+ import { getGlobalCacheDir, getGlobalCacheTierDirs, getGlobalConfigDir, getGlobalConfigPath, getLegacyGlobalConfigDir, getLegacyGlobalConfigPath, } from '../global-config.js';
3
+ export const PROJECT_STATE_DIR_NAME = '.sdd';
4
+ export const FORBIDDEN_PROJECT_RUNTIME_DIR_NAME = '.codesdd';
5
+ export function buildCodesddStorageBoundaryReport(projectRoot = process.cwd()) {
6
+ const normalizedProjectRoot = normalizePath(projectRoot);
7
+ return {
8
+ schema_version: 1,
9
+ project_root: normalizedProjectRoot,
10
+ project_state_dir: path.join(normalizedProjectRoot, PROJECT_STATE_DIR_NAME),
11
+ global_runtime_dir: getGlobalConfigDir(),
12
+ global_config_path: getGlobalConfigPath(),
13
+ global_cache_dir: getGlobalCacheDir(),
14
+ global_cache_tiers: getGlobalCacheTierDirs(),
15
+ legacy_config_path: getLegacyGlobalConfigPath(),
16
+ rules: {
17
+ versioned_project_state: 'Project decisions, backlog state, active/planned/archived features, ADRs, and docs live under .sdd and are versioned with the repository.',
18
+ global_runtime: 'Machine-level config, shell integration, provider settings, and reusable runtime files live under ~/.codesdd and are not repository state.',
19
+ global_cache: 'Cacheable derived data lives under ~/.codesdd/cache with project fingerprint isolation and can be discarded.',
20
+ forbidden_project_runtime: 'A project-local .codesdd directory is not canonical; use .sdd for project state and ~/.codesdd for runtime/cache.',
21
+ },
22
+ };
23
+ }
24
+ export function classifyCodesddStoragePath(targetPath, options = {}) {
25
+ const normalizedPath = normalizePath(targetPath);
26
+ const projectRoot = normalizePath(options.projectRoot ?? process.cwd());
27
+ const projectStateDir = path.join(projectRoot, PROJECT_STATE_DIR_NAME);
28
+ const forbiddenProjectRuntimeDir = path.join(projectRoot, FORBIDDEN_PROJECT_RUNTIME_DIR_NAME);
29
+ const globalConfigPath = normalizePath(getGlobalConfigPath());
30
+ const globalConfigDir = normalizePath(getGlobalConfigDir());
31
+ const globalCacheDir = normalizePath(getGlobalCacheDir());
32
+ const legacyConfigPath = normalizePath(getLegacyGlobalConfigPath());
33
+ const legacyConfigDir = normalizePath(getLegacyGlobalConfigDir());
34
+ if (isSameOrInside(normalizedPath, forbiddenProjectRuntimeDir)) {
35
+ return classification('invalid-project-runtime', normalizedPath, false, false, false, false, 'Project-local .codesdd is not canonical; use .sdd for project state or ~/.codesdd for runtime/cache.');
36
+ }
37
+ if (isSameOrInside(normalizedPath, projectStateDir)) {
38
+ return classification('project-state', normalizedPath, true, true, true, false, 'Versioned project governance, docs, decisions, and lifecycle state belong under .sdd.');
39
+ }
40
+ if (normalizedPath === globalConfigPath) {
41
+ return classification('global-config', normalizedPath, true, true, false, false, 'Machine-level CodeSDD configuration belongs in ~/.codesdd/config.toml and is not project state.');
42
+ }
43
+ if (isSameOrInside(normalizedPath, globalCacheDir)) {
44
+ return classification('global-cache', normalizedPath, true, true, false, true, 'Cacheable derived data belongs under ~/.codesdd/cache and must remain discardable.');
45
+ }
46
+ if (isSameOrInside(normalizedPath, globalConfigDir)) {
47
+ return classification('global-runtime', normalizedPath, true, true, false, false, 'Reusable machine runtime files belong under ~/.codesdd and are not repository state.');
48
+ }
49
+ if (normalizedPath === legacyConfigPath || isSameOrInside(normalizedPath, legacyConfigDir)) {
50
+ return classification('legacy-read-fallback', normalizedPath, true, false, false, false, 'Legacy global config is read only as a compatibility fallback; new runtime state belongs under ~/.codesdd.');
51
+ }
52
+ return classification('external', normalizedPath, true, false, false, false, 'Path is outside CodeSDD project state and global runtime boundaries.');
53
+ }
54
+ export function validateCodesddStoragePaths(targetPaths, options = {}) {
55
+ const classifications = targetPaths.map((targetPath) => classifyCodesddStoragePath(targetPath, options));
56
+ const findings = classifications
57
+ .filter((entry) => !entry.valid)
58
+ .map((entry) => ({
59
+ path: entry.path,
60
+ boundary: entry.boundary,
61
+ message: entry.reason,
62
+ }));
63
+ return {
64
+ valid: findings.length === 0,
65
+ findings,
66
+ classifications,
67
+ };
68
+ }
69
+ function classification(boundary, targetPath, valid, canonical, versioned, cacheable, reason) {
70
+ return {
71
+ boundary,
72
+ path: targetPath,
73
+ valid,
74
+ canonical,
75
+ versioned,
76
+ cacheable,
77
+ reason,
78
+ };
79
+ }
80
+ function normalizePath(input) {
81
+ return path.resolve(input);
82
+ }
83
+ function isSameOrInside(candidate, parent) {
84
+ if (candidate === parent) {
85
+ return true;
86
+ }
87
+ const relative = path.relative(parent, candidate);
88
+ return relative.length > 0 && !relative.startsWith('..') && !path.isAbsolute(relative);
89
+ }
90
+ //# sourceMappingURL=runtime-boundary-contract.js.map