aperta-cli 1.0.0-beta.1

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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +386 -0
  3. package/bin/aperta.js +3 -0
  4. package/dashboard/dist/assets/index-CWL1aA6j.js +11 -0
  5. package/dashboard/dist/assets/index-D0Ru46BW.css +1 -0
  6. package/dashboard/dist/index.html +15 -0
  7. package/dist-cli/src/adapters/git-only.js +7 -0
  8. package/dist-cli/src/adapters/git-only.js.map +1 -0
  9. package/dist-cli/src/adapters/opencode.js +47 -0
  10. package/dist-cli/src/adapters/opencode.js.map +1 -0
  11. package/dist-cli/src/agent-harness.js +1292 -0
  12. package/dist-cli/src/agent-harness.js.map +1 -0
  13. package/dist-cli/src/capture.js +17 -0
  14. package/dist-cli/src/capture.js.map +1 -0
  15. package/dist-cli/src/cli.js +283 -0
  16. package/dist-cli/src/cli.js.map +1 -0
  17. package/dist-cli/src/coach.js +315 -0
  18. package/dist-cli/src/coach.js.map +1 -0
  19. package/dist-cli/src/dashboard-data.js +254 -0
  20. package/dist-cli/src/dashboard-data.js.map +1 -0
  21. package/dist-cli/src/dashboard-server.js +379 -0
  22. package/dist-cli/src/dashboard-server.js.map +1 -0
  23. package/dist-cli/src/engine.js +85 -0
  24. package/dist-cli/src/engine.js.map +1 -0
  25. package/dist-cli/src/execution.js +20 -0
  26. package/dist-cli/src/execution.js.map +1 -0
  27. package/dist-cli/src/git.js +131 -0
  28. package/dist-cli/src/git.js.map +1 -0
  29. package/dist-cli/src/harness-intelligence.js +110 -0
  30. package/dist-cli/src/harness-intelligence.js.map +1 -0
  31. package/dist-cli/src/hook.js +39 -0
  32. package/dist-cli/src/hook.js.map +1 -0
  33. package/dist-cli/src/impact.js +224 -0
  34. package/dist-cli/src/impact.js.map +1 -0
  35. package/dist-cli/src/jobs.js +27 -0
  36. package/dist-cli/src/jobs.js.map +1 -0
  37. package/dist-cli/src/ledger.js +211 -0
  38. package/dist-cli/src/ledger.js.map +1 -0
  39. package/dist-cli/src/map.js +73 -0
  40. package/dist-cli/src/map.js.map +1 -0
  41. package/dist-cli/src/observer.js +127 -0
  42. package/dist-cli/src/observer.js.map +1 -0
  43. package/dist-cli/src/probes.js +195 -0
  44. package/dist-cli/src/probes.js.map +1 -0
  45. package/dist-cli/src/prompt.js +44 -0
  46. package/dist-cli/src/prompt.js.map +1 -0
  47. package/dist-cli/src/proof-graph.js +123 -0
  48. package/dist-cli/src/proof-graph.js.map +1 -0
  49. package/dist-cli/src/proof.js +99 -0
  50. package/dist-cli/src/proof.js.map +1 -0
  51. package/dist-cli/src/registry.js +60 -0
  52. package/dist-cli/src/registry.js.map +1 -0
  53. package/dist-cli/src/repository.js +39 -0
  54. package/dist-cli/src/repository.js.map +1 -0
  55. package/dist-cli/src/semantic.js +183 -0
  56. package/dist-cli/src/semantic.js.map +1 -0
  57. package/dist-cli/src/service.js +60 -0
  58. package/dist-cli/src/service.js.map +1 -0
  59. package/dist-cli/src/session.js +41 -0
  60. package/dist-cli/src/session.js.map +1 -0
  61. package/dist-cli/src/settings.js +305 -0
  62. package/dist-cli/src/settings.js.map +1 -0
  63. package/dist-cli/src/skills.js +104 -0
  64. package/dist-cli/src/skills.js.map +1 -0
  65. package/dist-cli/src/storage.js +163 -0
  66. package/dist-cli/src/storage.js.map +1 -0
  67. package/dist-cli/src/types.js +2 -0
  68. package/dist-cli/src/types.js.map +1 -0
  69. package/package.json +56 -0
@@ -0,0 +1,195 @@
1
+ import { createHash } from "node:crypto";
2
+ import { execFile } from "node:child_process";
3
+ import { promisify } from "node:util";
4
+ import { chmod, cp, mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
5
+ import { dirname, join, relative, sep } from "node:path";
6
+ import { tmpdir } from "node:os";
7
+ import { appendEvent, eventBase, readLedger } from "./ledger.js";
8
+ import { cleanExecutionOutput, safeEnvironment } from "./execution.js";
9
+ const execFileAsync = promisify(execFile);
10
+ const active = new Set();
11
+ const commonImports = `import org.junit.jupiter.api.Test;
12
+ import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
13
+ import org.springframework.security.oauth2.jwt.JwtClaimsSet;
14
+ import org.springframework.security.oauth2.jwt.JwtDecoder;
15
+ import org.springframework.security.oauth2.jwt.JwtEncoder;
16
+ import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
17
+ import org.springframework.security.oauth2.jwt.JwtException;
18
+ import org.springframework.security.oauth2.jwt.JwsHeader;
19
+
20
+ import javax.crypto.SecretKey;
21
+ import java.nio.charset.StandardCharsets;
22
+ import java.time.Duration;
23
+ import java.time.Instant;
24
+ import java.util.Base64;
25
+ import java.util.UUID;
26
+
27
+ import static org.assertj.core.api.Assertions.assertThatThrownBy;`;
28
+ const helpers = ` private static JwtProperties properties(String rawKey, String issuer) {
29
+ return new JwtProperties(Base64.getEncoder().encodeToString(rawKey.getBytes(StandardCharsets.UTF_8)),
30
+ issuer, Duration.ofMinutes(15), Duration.ofDays(7));
31
+ }
32
+
33
+ private static String encode(JwtEncoder encoder, String issuer, String subject, Instant issuedAt, Instant expiresAt) {
34
+ JwtClaimsSet claims = JwtClaimsSet.builder().issuer(issuer).subject(subject)
35
+ .issuedAt(issuedAt).expiresAt(expiresAt).build();
36
+ return encoder.encode(JwtEncoderParameters.from(
37
+ JwsHeader.with(MacAlgorithm.HS256).build(), claims)).getTokenValue();
38
+ }`;
39
+ function javaSource(packageName, probeId) {
40
+ const test = probeId === "jwt-expired"
41
+ ? ` @Test
42
+ void rejectsExpiredToken() {
43
+ JwtProperties properties = properties("expired-probe-key-with-at-least-32-bytes", "auth-service");
44
+ SecurityConfig configuration = new SecurityConfig();
45
+ SecretKey key = configuration.jwtSigningKey(properties);
46
+ JwtDecoder decoder = configuration.jwtDecoder(key, properties);
47
+ Instant now = Instant.now();
48
+ String token = encode(configuration.jwtEncoder(key), properties.issuer(), UUID.randomUUID().toString(),
49
+ now.minusSeconds(120), now.minusSeconds(60));
50
+
51
+ assertThatThrownBy(() -> decoder.decode(token)).isInstanceOf(JwtException.class);
52
+ }`
53
+ : probeId === "jwt-issuer"
54
+ ? ` @Test
55
+ void rejectsTokenFromIncorrectIssuer() {
56
+ JwtProperties properties = properties("issuer-probe-key-with-at-least-32-bytes", "auth-service");
57
+ SecurityConfig configuration = new SecurityConfig();
58
+ SecretKey key = configuration.jwtSigningKey(properties);
59
+ JwtDecoder decoder = configuration.jwtDecoder(key, properties);
60
+ Instant now = Instant.now();
61
+ String token = encode(configuration.jwtEncoder(key), "another-issuer", UUID.randomUUID().toString(),
62
+ now, now.plusSeconds(60));
63
+
64
+ assertThatThrownBy(() -> decoder.decode(token)).isInstanceOf(JwtException.class);
65
+ }`
66
+ : ` @Test
67
+ void rejectsTokenWithInvalidSignature() {
68
+ JwtProperties signingProperties = properties("signing-probe-key-with-at-least-32-bytes", "auth-service");
69
+ JwtProperties verifyingProperties = properties("different-verification-key-32-bytes!", "auth-service");
70
+ SecurityConfig configuration = new SecurityConfig();
71
+ SecretKey signingKey = configuration.jwtSigningKey(signingProperties);
72
+ SecretKey verifyingKey = configuration.jwtSigningKey(verifyingProperties);
73
+ JwtDecoder decoder = configuration.jwtDecoder(verifyingKey, verifyingProperties);
74
+ Instant now = Instant.now();
75
+ String token = encode(configuration.jwtEncoder(signingKey), signingProperties.issuer(),
76
+ UUID.randomUUID().toString(), now, now.plusSeconds(60));
77
+
78
+ assertThatThrownBy(() -> decoder.decode(token)).isInstanceOf(JwtException.class);
79
+ }`;
80
+ return `package ${packageName};
81
+
82
+ ${commonImports}
83
+
84
+ class ApertaGeneratedSecurityProbeTest {
85
+
86
+ ${test}
87
+
88
+ ${helpers}
89
+ }
90
+ `;
91
+ }
92
+ function endpointScaffold(packageName) {
93
+ return `package ${packageName};
94
+
95
+ // Aperta needs one concrete protected route and the repository's preferred
96
+ // Spring test slice before this integration probe can execute safely.
97
+ // Intended assertion: an unauthenticated request is rejected, while the same
98
+ // request with a decoder-accepted JWT reaches the protected endpoint.
99
+ class ApertaGeneratedEndpointAuthorizationProbeTest {}
100
+ `;
101
+ }
102
+ function targets(graph, patterns) {
103
+ return graph.nodes.filter((node) => patterns.some((pattern) => pattern.test(`${node.label} ${node.detail ?? ""}`))).map((node) => node.id);
104
+ }
105
+ async function javaContext(root, diff) {
106
+ const test = diff.files.find((file) => /JwtConfigurationTests\.java$/.test(file.path));
107
+ if (!test)
108
+ return null;
109
+ let source = "";
110
+ try {
111
+ source = await readFile(join(root, test.path), "utf8");
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ const packageName = source.match(/^package\s+([\w.]+);/m)?.[1];
117
+ if (!packageName)
118
+ return null;
119
+ return { packageName, generatedPath: join(dirname(test.path), "ApertaGeneratedSecurityProbeTest.java") };
120
+ }
121
+ export async function generateProbes(root, diff, graph) {
122
+ const context = await javaContext(root, diff);
123
+ if (!context || !/JwtAuthenticationFilter|OAuth2 resource server/.test(`${graph.headline} ${graph.nodes.map((node) => node.label).join(" ")}`))
124
+ return [];
125
+ const command = "./mvnw -q -Dtest=ApertaGeneratedSecurityProbeTest test";
126
+ const decoderTargets = targets(graph, [/JwtDecoder/i, /resource server/i, /jwtDecoder/i]);
127
+ const definitions = [
128
+ { id: "jwt-expired", label: "Expired token rejection", hypothesis: "The configured decoder rejects a correctly signed token after its expiration instant.", why: "Default timestamp validation is assumed but has not been executed against this configuration.", language: "java", framework: "JUnit 5 + AssertJ", readiness: "ready", executable: true, patterns: [/JwtDecoder/i, /resource server/i, /jwtDecoder/i] },
129
+ { id: "jwt-issuer", label: "Incorrect issuer rejection", hypothesis: "The configured decoder rejects a valid signature when the issuer claim does not match JwtProperties.", why: "Issuer validation was added as configuration and needs executable evidence.", language: "java", framework: "JUnit 5 + AssertJ", readiness: "ready", executable: true, patterns: [/JwtIssuerValidator/i, /JwtDecoder/i, /jwtDecoder/i] },
130
+ { id: "jwt-signature", label: "Invalid signature rejection", hypothesis: "The configured decoder rejects a token signed with a different HS256 key.", why: "Signing-key mismatch is a critical authentication boundary not covered by the changed tests.", language: "java", framework: "JUnit 5 + AssertJ", readiness: "ready", executable: true, patterns: [/SecretKey/i, /JwtDecoder/i, /jwtDecoder/i] },
131
+ { id: "jwt-endpoint", label: "Endpoint authorization boundaries", hypothesis: "Protected endpoints reject anonymous requests and accept decoder-approved bearer tokens.", why: "No concrete protected controller route exists in the current repository, so Aperta will not invent an integration target.", language: "java", framework: "Spring MockMvc", readiness: "needs-context", executable: false, patterns: [/HTTP API/i, /SecurityFilterChain/i, /securityFilterChain/i] },
132
+ ];
133
+ return definitions.map((definition) => ({
134
+ id: definition.id, label: definition.label, hypothesis: definition.hypothesis, why: definition.why,
135
+ language: definition.language, framework: definition.framework, readiness: definition.readiness,
136
+ generatedPath: definition.id === "jwt-endpoint" ? context.generatedPath.replace("SecurityProbe", "EndpointAuthorizationProbe") : context.generatedPath,
137
+ source: definition.id === "jwt-endpoint" ? endpointScaffold(context.packageName) : javaSource(context.packageName, definition.id),
138
+ command: definition.executable ? command : undefined,
139
+ targetNodeIds: definition.patterns.length ? targets(graph, definition.patterns) : decoderTargets,
140
+ }));
141
+ }
142
+ export async function probeHistory(root, diffId) {
143
+ return (await readLedger(root)).filter((event) => event.kind === "probe" && event.diffId === diffId).sort((a, b) => b.ts.localeCompare(a.ts));
144
+ }
145
+ export async function executeProbe(root, diff, probe, signal) {
146
+ if (probe.readiness !== "ready" || !probe.command)
147
+ throw new Error("This probe needs repository context before it can run.");
148
+ const key = `${root}:${diff.id}:${probe.id}`;
149
+ if (active.has(key))
150
+ throw new Error("This probe is already running.");
151
+ active.add(key);
152
+ const temp = await mkdtemp(join(tmpdir(), "aperta-probe-"));
153
+ const isolatedRoot = join(temp, "repo");
154
+ const started = Date.now();
155
+ let exitCode = 0;
156
+ let output = "";
157
+ try {
158
+ await cp(root, isolatedRoot, { recursive: true, filter: (source) => {
159
+ const parts = relative(root, source).split(sep);
160
+ return !parts.some((part) => [".git", ".comprehension", "node_modules", "target", "build", ".gradle"].includes(part));
161
+ } });
162
+ const destination = join(isolatedRoot, probe.generatedPath);
163
+ await mkdir(dirname(destination), { recursive: true });
164
+ await writeFile(destination, probe.source, "utf8");
165
+ try {
166
+ await chmod(join(isolatedRoot, "mvnw"), 0o755);
167
+ }
168
+ catch { }
169
+ try {
170
+ const result = await execFileAsync("./mvnw", ["-q", "-Dtest=ApertaGeneratedSecurityProbeTest", "test"], { cwd: isolatedRoot, timeout: 5 * 60_000, maxBuffer: 4 * 1024 * 1024, env: safeEnvironment(), signal });
171
+ output = `${result.stdout}${result.stderr}`;
172
+ }
173
+ catch (error) {
174
+ const failure = error;
175
+ exitCode = typeof failure.code === "number" ? failure.code : null;
176
+ output = `${failure.stdout ?? ""}${failure.stderr ?? ""}${failure.killed ? "\nProbe timed out after five minutes." : ""}`;
177
+ }
178
+ }
179
+ finally {
180
+ await rm(temp, { recursive: true, force: true });
181
+ active.delete(key);
182
+ }
183
+ if (signal?.aborted)
184
+ throw new Error("Probe canceled");
185
+ const cleaned = cleanExecutionOutput(output);
186
+ const status = exitCode === 0 ? "proven" : /Tests run:|Failures:|AssertionError|expected:/i.test(cleaned) ? "disproven" : "inconclusive";
187
+ const event = {
188
+ ...eventBase(root, diff.branch), kind: "probe", diffId: diff.id, probeId: probe.id, label: probe.label, status,
189
+ command: probe.command, durationMs: Date.now() - started, exitCode, output: cleaned, generatedPath: probe.generatedPath,
190
+ sourceHash: createHash("sha256").update(probe.source).digest("hex"), targetNodeIds: probe.targetNodeIds,
191
+ };
192
+ await appendEvent(root, event);
193
+ return event;
194
+ }
195
+ //# sourceMappingURL=probes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probes.js","sourceRoot":"","sources":["../../src/probes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ async function singleKey(valid, timeoutMs) {
2
+ if (!process.stdin.isTTY)
3
+ return null;
4
+ process.stdin.setRawMode(true);
5
+ process.stdin.resume();
6
+ process.stdin.setEncoding("utf8");
7
+ return new Promise((resolve) => {
8
+ let timer;
9
+ const finish = (value) => {
10
+ if (timer)
11
+ clearTimeout(timer);
12
+ process.stdin.off("data", onData);
13
+ process.stdin.setRawMode(false);
14
+ process.stdin.pause();
15
+ resolve(value);
16
+ };
17
+ const onData = (key) => {
18
+ if (key === "\u0003") {
19
+ finish(null);
20
+ process.kill(process.pid, "SIGINT");
21
+ }
22
+ else if (key === "\u001b")
23
+ finish(null);
24
+ else if (valid.has(key))
25
+ finish(key);
26
+ };
27
+ process.stdin.on("data", onData);
28
+ if (timeoutMs)
29
+ timer = setTimeout(() => finish(null), timeoutMs);
30
+ });
31
+ }
32
+ export async function promptAuthorship() {
33
+ process.stdout.write("Authorship: [a]i [h]uman [m]ixed [esc] skip ");
34
+ const key = await singleKey(new Set(["a", "h", "m"]));
35
+ process.stdout.write(key ? `${key}\n` : "skipped\n");
36
+ return key === "a" ? "ai" : key === "h" ? "human" : key === "m" ? "mixed" : null;
37
+ }
38
+ export async function promptConfidence(timeoutSeconds) {
39
+ process.stdout.write("Confidence: [1] opaque [2] followable [3] owned [esc] skip ");
40
+ const key = await singleKey(new Set(["1", "2", "3"]), timeoutSeconds * 1000);
41
+ process.stdout.write(key ? `${key}\n` : "unrated\n");
42
+ return key ? Number(key) : null;
43
+ }
44
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/prompt.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,SAAS,CAAC,KAAkB,EAAE,SAAkB;IAC7D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,KAAiC,CAAC;QACtC,MAAM,MAAM,GAAG,CAAC,KAAoB,EAAE,EAAE;YACtC,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,EAAE;YAC7B,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACrB,MAAM,CAAC,IAAI,CAAC,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACtC,CAAC;iBAAM,IAAI,GAAG,KAAK,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,CAAC;iBACrC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,IAAI,SAAS;YAAE,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACzE,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACrD,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACnF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,cAAsB;IAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACxF,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC,CAAC;IAC7E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACrD,OAAO,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAoB,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC"}
@@ -0,0 +1,123 @@
1
+ import { listAgentRuns } from "./agent-harness.js";
2
+ import { readLedger } from "./ledger.js";
3
+ function unique(values) { return [...new Set(values.filter(Boolean))]; }
4
+ function latestTimestamp(values) {
5
+ return values.filter((value) => Boolean(value)).sort().at(-1) ?? null;
6
+ }
7
+ function intersects(left, right) {
8
+ const paths = new Set(left);
9
+ return right.filter((path) => paths.has(path));
10
+ }
11
+ function summaryForRun(run) {
12
+ return run.summary?.trim() || run.understanding?.changedBehavior?.trim() || run.intent.trim() || "Agent repository change";
13
+ }
14
+ function runEvidence(run) {
15
+ const skill = [{ id: `run:${run.id}:skill:${run.skill.id}`, kind: "skill", label: run.skill.label, status: "selected", detail: `${run.skill.description} Proof contract: ${run.skill.proof.map((item) => item.text).join(" ")}`, ts: run.createdAt }];
16
+ const verification = run.verification.attempts.flatMap((attempt) => attempt.checks.map((check) => ({
17
+ id: `run:${run.id}:check:${attempt.index}:${check.id}`,
18
+ kind: "verification",
19
+ label: check.label,
20
+ status: check.status,
21
+ detail: `${check.command} · ${check.status}${check.exitCode == null ? "" : ` (exit ${check.exitCode})`}`,
22
+ ts: attempt.ts,
23
+ })));
24
+ const capabilities = run.capabilities.map((capability) => ({
25
+ id: `run:${run.id}:capability:${capability.id}`,
26
+ kind: "capability",
27
+ label: capability.label,
28
+ status: capability.status,
29
+ detail: capability.summary,
30
+ ts: capability.ts,
31
+ }));
32
+ const understanding = run.understanding?.completedAt ? [{
33
+ id: `run:${run.id}:understanding`,
34
+ kind: "ownership",
35
+ label: "Understanding demonstrated",
36
+ status: "completed",
37
+ detail: `${Object.values(run.understanding.responses).filter((answer) => answer.trim()).length} ownership responses retained locally.`,
38
+ ts: run.understanding.completedAt,
39
+ }] : [];
40
+ return [...skill, ...verification, ...capabilities, ...understanding];
41
+ }
42
+ function claimForRun(run) {
43
+ const evidence = runEvidence(run);
44
+ const files = unique(run.files.map((file) => file.path));
45
+ if (!files.length && !evidence.length)
46
+ return null;
47
+ const passed = run.verification.status === "passed";
48
+ const failed = run.verification.status === "failed";
49
+ const understood = Boolean(run.understanding?.completedAt);
50
+ const supported = evidence.some((item) => item.kind === "capability" && ["passed", "reachable", "running", "success"].includes(item.status));
51
+ const status = failed ? "regressed" : passed ? "proven" : understood ? "understood" : supported ? "supported" : "unproven";
52
+ const assuranceAt = latestTimestamp(evidence.filter((item) => ["passed", "completed", "reachable", "running", "success"].includes(item.status)).map((item) => item.ts));
53
+ return {
54
+ id: `run:${run.id}`, source: "agent-run", title: run.intent.trim() || "Agent task", detail: summaryForRun(run), ts: run.createdAt,
55
+ files, status, evidence, assuranceAt, invalidatedFiles: [],
56
+ };
57
+ }
58
+ function claimForDiff(diff, events) {
59
+ const proofs = events.filter((event) => event.kind === "proof" && event.diffId === diff.id);
60
+ const ownership = events.filter((event) => event.kind === "ownership-evidence" && event.diffId === diff.id);
61
+ const completions = events.filter((event) => event.kind === "session-complete" && event.diffId === diff.id);
62
+ const evidence = [
63
+ ...proofs.map((proof) => ({ id: `diff:${diff.id}:proof:${proof.id}`, kind: "proof", label: proof.command, status: proof.status, detail: `${proof.runner} proof ${proof.status} in ${(proof.durationMs / 1000).toFixed(1)}s.`, ts: proof.ts })),
64
+ ...ownership.map((item) => ({ id: `diff:${diff.id}:ownership:${item.id}`, kind: "ownership", label: "Ownership evidence", status: item.completedCount >= item.requiredCount ? "completed" : "partial", detail: `${item.completedCount}/${item.requiredCount} required answers completed.`, ts: item.ts })),
65
+ ...completions.map((item) => ({ id: `diff:${diff.id}:completion:${item.id}`, kind: "completion", label: "Ownership session", status: "completed", detail: `Confidence ${item.score}/3 with ${item.evidenceCount} evidence responses.`, ts: item.ts })),
66
+ ];
67
+ const latestProof = proofs.slice().sort((a, b) => b.ts.localeCompare(a.ts))[0];
68
+ const understood = ownership.some((item) => item.completedCount >= item.requiredCount) || completions.length > 0;
69
+ const status = latestProof?.status === "regressed" ? "regressed" : latestProof?.status === "proven" ? "proven" : understood ? "understood" : "unproven";
70
+ const assuranceAt = latestTimestamp(evidence.filter((item) => item.status === "proven" || item.status === "completed").map((item) => item.ts));
71
+ const title = diff.files.map((file) => file.path.split("/").at(-1)).slice(0, 2).join(", ") || "Captured repository change";
72
+ return { id: `diff:${diff.id}`, source: "captured-change", title, detail: `${diff.files.length} captured file${diff.files.length === 1 ? "" : "s"} · ${diff.model ?? diff.authorship}`, ts: diff.ts, files: unique(diff.files.map((file) => file.path)), status, evidence, assuranceAt, invalidatedFiles: [] };
73
+ }
74
+ function applyInvalidation(claim, changes) {
75
+ if (!claim.files.length)
76
+ return claim;
77
+ const currentAt = claim.assuranceAt ?? claim.ts;
78
+ const invalidator = changes
79
+ .filter((change) => change.id !== claim.id && change.ts > currentAt && intersects(claim.files, change.files).length)
80
+ .sort((a, b) => b.ts.localeCompare(a.ts))[0];
81
+ if (!invalidator)
82
+ return claim;
83
+ return { ...claim, status: "stale", invalidatedAt: invalidator.ts, invalidatedBy: invalidator.title, invalidatedFiles: intersects(claim.files, invalidator.files) };
84
+ }
85
+ export function buildRepositoryProofGraph(runs, events, generatedAt = new Date().toISOString()) {
86
+ const diffs = events.filter((event) => event.kind === "diff");
87
+ const initialClaims = [...runs.map(claimForRun).filter((claim) => Boolean(claim)), ...diffs.map((diff) => claimForDiff(diff, events))];
88
+ const changes = [
89
+ ...runs.filter((run) => run.files.length).map((run) => ({ id: `run:${run.id}`, ts: run.finishedAt ?? run.createdAt, title: run.intent.trim() || "A later agent run", files: run.files.map((file) => file.path) })),
90
+ ...diffs.map((diff) => ({ id: `diff:${diff.id}`, ts: diff.ts, title: diff.files.map((file) => file.path.split("/").at(-1)).slice(0, 2).join(", ") || "A later captured change", files: diff.files.map((file) => file.path) })),
91
+ ];
92
+ const claims = initialClaims.map((claim) => applyInvalidation(claim, changes)).sort((a, b) => b.ts.localeCompare(a.ts));
93
+ const nodes = [];
94
+ const edges = [];
95
+ const nodeIds = new Set();
96
+ const addNode = (node) => { if (!nodeIds.has(node.id)) {
97
+ nodeIds.add(node.id);
98
+ nodes.push(node);
99
+ } };
100
+ for (const claim of claims) {
101
+ addNode({ id: claim.id, kind: "claim", label: claim.title, status: claim.status, detail: claim.detail });
102
+ for (const path of claim.files) {
103
+ const fileId = `file:${path}`;
104
+ addNode({ id: fileId, kind: "file", label: path.split("/").at(-1) ?? path, status: claim.status, path });
105
+ edges.push({ from: claim.id, to: fileId, relation: "affects" });
106
+ }
107
+ for (const evidence of claim.evidence) {
108
+ addNode({ id: evidence.id, kind: "evidence", label: evidence.label, status: evidence.status, detail: evidence.detail });
109
+ const relation = evidence.kind === "ownership" || evidence.kind === "completion" ? "understands" : evidence.kind === "capability" || evidence.kind === "skill" ? "observes" : "proves";
110
+ edges.push({ from: evidence.id, to: claim.id, relation });
111
+ }
112
+ if (claim.invalidatedAt)
113
+ for (const path of claim.invalidatedFiles)
114
+ edges.push({ from: `file:${path}`, to: claim.id, relation: "invalidates" });
115
+ }
116
+ const count = (status) => claims.filter((claim) => claim.status === status).length;
117
+ return { generatedAt, claims, nodes, edges, summary: { claims: claims.length, proven: count("proven"), understood: count("understood"), supported: count("supported"), stale: count("stale"), regressed: count("regressed"), unproven: count("unproven"), coveredFiles: new Set(claims.flatMap((claim) => claim.files)).size } };
118
+ }
119
+ export async function loadRepositoryProofGraph(root) {
120
+ const [runs, events] = await Promise.all([listAgentRuns(root, Number.POSITIVE_INFINITY), readLedger(root)]);
121
+ return buildRepositoryProofGraph(runs, events);
122
+ }
123
+ //# sourceMappingURL=proof-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proof-graph.js","sourceRoot":"","sources":["../../src/proof-graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { access, mkdir, readFile } from "node:fs/promises";
4
+ import { basename, join } from "node:path";
5
+ import { appendEvent, eventBase, readLedger } from "./ledger.js";
6
+ import { currentBranch } from "./git.js";
7
+ import { cleanExecutionOutput, safeEnvironment } from "./execution.js";
8
+ import { privateCachePath } from "./storage.js";
9
+ const execFileAsync = promisify(execFile);
10
+ const running = new Set();
11
+ async function exists(path) { try {
12
+ await access(path);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ } }
18
+ function coveredNodes(graph) {
19
+ const tests = new Set(graph.nodes.filter((node) => node.kind === "test").map((node) => node.id));
20
+ return [...new Set([...tests, ...graph.edges.filter((edge) => edge.kind === "covers" && tests.has(edge.from)).map((edge) => edge.to)])];
21
+ }
22
+ export async function buildProofPlan(root, diff, graph) {
23
+ const javaTests = diff.files.filter((file) => /(?:Test|Tests)\.java$/.test(file.path)).map((file) => basename(file.path, ".java")).filter((name) => /^[A-Za-z_$][\w$]*$/.test(name));
24
+ const jsTests = diff.files.filter((file) => /(^|\/)(test|tests|__tests__)(\/|$)|\.(test|spec)\.[cm]?[jt]sx?$/i.test(file.path)).map((file) => file.path);
25
+ const proposedProbes = graph.unproven.map((label, index) => ({ id: `probe-${index + 1}`, label, reason: "No executed evidence currently covers this behavior." }));
26
+ const base = { available: true, scope: "Relevant changed tests", tests: javaTests.length ? javaTests : jsTests, coveredNodeIds: coveredNodes(graph), proposedProbes };
27
+ if (await exists(join(root, "pom.xml"))) {
28
+ const wrapper = await exists(join(root, "mvnw"));
29
+ const args = ["-q", ...(javaTests.length ? [`-Dtest=${javaTests.join(",")}`] : []), "test"];
30
+ return { ...base, runner: "maven", executable: wrapper ? "./mvnw" : "mvn", args, command: `${wrapper ? "./mvnw" : "mvn"} ${args.join(" ")}`, scope: javaTests.length ? `${javaTests.length} changed Java test class${javaTests.length === 1 ? "" : "es"}` : "Full Maven test suite" };
31
+ }
32
+ if (await exists(join(root, "build.gradle")) || await exists(join(root, "build.gradle.kts"))) {
33
+ const wrapper = await exists(join(root, "gradlew"));
34
+ const args = ["test", ...javaTests.flatMap((name) => ["--tests", `*${name}`])];
35
+ return { ...base, runner: "gradle", executable: wrapper ? "./gradlew" : "gradle", args, command: `${wrapper ? "./gradlew" : "gradle"} ${args.join(" ")}`, scope: javaTests.length ? `${javaTests.length} changed Java test class${javaTests.length === 1 ? "" : "es"}` : "Full Gradle test suite" };
36
+ }
37
+ if (await exists(join(root, "package.json"))) {
38
+ const manifest = JSON.parse(await readFile(join(root, "package.json"), "utf8"));
39
+ if (!manifest.scripts?.test)
40
+ return { ...base, available: false, scope: "No test script found" };
41
+ const runner = await exists(join(root, "pnpm-lock.yaml")) ? "pnpm" : await exists(join(root, "yarn.lock")) ? "yarn" : "npm";
42
+ const executable = runner;
43
+ const args = runner === "npm" ? ["test"] : ["test"];
44
+ return { ...base, runner, executable, args, command: `${runner} test`, scope: "Project test script" };
45
+ }
46
+ return { ...base, available: false, scope: "No supported Java or TypeScript test runner detected" };
47
+ }
48
+ export async function runProof(root, diff, plan, signal) {
49
+ if (!plan.available || !plan.runner || !plan.executable || !plan.args || !plan.command)
50
+ throw new Error("No supported proof runner is available for this capture.");
51
+ const key = `${root}:${diff.id}`;
52
+ if (running.has(key))
53
+ throw new Error("Proof is already running for this capture.");
54
+ running.add(key);
55
+ const started = Date.now();
56
+ let exitCode = 0;
57
+ let output = "";
58
+ try {
59
+ const result = await execFileAsync(plan.executable, plan.args, { cwd: root, timeout: 5 * 60_000, maxBuffer: 4 * 1024 * 1024, env: safeEnvironment(), signal });
60
+ output = `${result.stdout}${result.stderr}`;
61
+ }
62
+ catch (error) {
63
+ const failure = error;
64
+ exitCode = typeof failure.code === "number" ? failure.code : null;
65
+ output = `${failure.stdout ?? ""}${failure.stderr ?? ""}${failure.killed ? "\nProof timed out after five minutes." : ""}`;
66
+ }
67
+ finally {
68
+ running.delete(key);
69
+ }
70
+ if (signal?.aborted)
71
+ throw new Error("Proof canceled");
72
+ const event = {
73
+ ...eventBase(root, diff.branch || await currentBranch(root)), kind: "proof", diffId: diff.id, runner: plan.runner, command: plan.command,
74
+ status: exitCode === 0 ? "proven" : exitCode === null ? "inconclusive" : "regressed", exitCode, durationMs: Date.now() - started,
75
+ output: cleanExecutionOutput(output), coveredNodeIds: exitCode === 0 ? plan.coveredNodeIds : [],
76
+ };
77
+ await appendEvent(root, event);
78
+ if (exitCode === 0 && plan.runner === "maven" && plan.executable) {
79
+ const semanticDir = privateCachePath(root, "semantic");
80
+ await mkdir(semanticDir, { recursive: true });
81
+ try {
82
+ await execFileAsync(plan.executable, ["-q", "dependency:build-classpath", `-Dmdep.outputFile=${join(semanticDir, "java-classpath.txt")}`], { cwd: root, timeout: 90_000, maxBuffer: 1024 * 1024, env: safeEnvironment(), signal });
83
+ }
84
+ catch { }
85
+ }
86
+ return event;
87
+ }
88
+ export async function proofHistory(root, diffId) {
89
+ return (await readLedger(root)).filter((event) => event.kind === "proof" && event.diffId === diffId).sort((a, b) => b.ts.localeCompare(a.ts));
90
+ }
91
+ export function nodeVerdicts(graph, latest) {
92
+ const covered = new Set(latest?.coveredNodeIds ?? []);
93
+ return graph.nodes.map((node) => ({
94
+ nodeId: node.id,
95
+ verdict: latest?.status === "regressed" && graph.edges.some((edge) => edge.kind === "covers" && edge.to === node.id) ? "regressed"
96
+ : covered.has(node.id) ? "proven" : node.status === "related" ? "inferred" : "unproven",
97
+ }));
98
+ }
99
+ //# sourceMappingURL=proof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proof.js","sourceRoot":"","sources":["../../src/proof.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { createHash } from "node:crypto";
2
+ import { homedir } from "node:os";
3
+ import { basename, join, resolve } from "node:path";
4
+ import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
5
+ function registryDir() { return process.env.APERTA_HOME ? resolve(process.env.APERTA_HOME) : join(homedir(), ".aperta"); }
6
+ function registryFile() { return join(registryDir(), "projects.json"); }
7
+ export function projectId(root) { return createHash("sha256").update(resolve(root)).digest("hex").slice(0, 16); }
8
+ async function readRaw() {
9
+ try {
10
+ const parsed = JSON.parse(await readFile(registryFile(), "utf8"));
11
+ return Array.isArray(parsed.projects) ? parsed.projects : [];
12
+ }
13
+ catch (error) {
14
+ if (error.code === "ENOENT")
15
+ return [];
16
+ throw error;
17
+ }
18
+ }
19
+ async function writeRegistry(projects) {
20
+ await mkdir(registryDir(), { recursive: true });
21
+ const temporary = join(registryDir(), `projects.${process.pid}.tmp`);
22
+ await writeFile(temporary, `${JSON.stringify({ version: 1, projects }, null, 2)}\n`, "utf8");
23
+ await rename(temporary, registryFile());
24
+ }
25
+ export async function registerProject(root, now = new Date()) {
26
+ const canonical = resolve(root);
27
+ const projects = await readRaw();
28
+ const id = projectId(canonical);
29
+ const existing = projects.find((project) => project.id === id);
30
+ const entry = {
31
+ id, name: basename(canonical), root: canonical,
32
+ addedAt: existing?.addedAt ?? now.toISOString(), lastOpenedAt: now.toISOString(),
33
+ };
34
+ await writeRegistry([entry, ...projects.filter((project) => project.id !== id)]);
35
+ return entry;
36
+ }
37
+ export async function listProjects() {
38
+ const projects = await readRaw();
39
+ return Promise.all(projects.map(async (project) => {
40
+ try {
41
+ const git = await stat(join(project.root, ".git"));
42
+ return { ...project, available: git.isDirectory() || git.isFile() };
43
+ }
44
+ catch {
45
+ return { ...project, available: false };
46
+ }
47
+ }));
48
+ }
49
+ export async function resolveProject(id, fallbackRoot) {
50
+ const fallbackId = projectId(fallbackRoot);
51
+ const projects = await listProjects();
52
+ const fallback = projects.find((entry) => entry.id === fallbackId) ?? await registerProject(fallbackRoot);
53
+ if (!id || id === fallback.id)
54
+ return fallback;
55
+ const project = projects.find((entry) => entry.id === id && entry.available);
56
+ if (!project)
57
+ throw new Error("Project is not registered or is unavailable");
58
+ return project;
59
+ }
60
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"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"}