jules-orchestrator-kit 0.42.0 → 0.52.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.
@@ -0,0 +1,86 @@
1
+ import { execSync } from "node:child_process";
2
+ import { resolveVerify } from "./config.mjs";
3
+ import { computeOscillation } from "./flaky-ledger.mjs";
4
+
5
+ /**
6
+ * Executes a test command repeatedly to probe for race conditions, non-deterministic timers, or test flakiness.
7
+ *
8
+ * @param {string} [testCmd] - Test command to execute repeatedly
9
+ * @param {object} [options]
10
+ * @param {string} [options.root=process.cwd()] - Project root directory
11
+ * @param {number} [options.repeat=5] - Number of consecutive iterations to execute
12
+ * @param {number} [options.minPassRate=1.0] - Required minimum pass rate (0.0 - 1.0)
13
+ * @param {number} [options.timeoutMs=30000] - Timeout per iteration in milliseconds
14
+ * @returns {object} { ok, repeat, passes, failures, passRate, oscillation, runs, durationMs, summary }
15
+ */
16
+ export function runStabilityProbe(testCmd, options = {}) {
17
+ const root = options.root || process.cwd();
18
+ const cmd = testCmd || resolveVerify(root).testCmd || "npm test";
19
+ const repeat = typeof options.repeat === "number" && options.repeat > 0 ? options.repeat : 5;
20
+ const minPassRate = typeof options.minPassRate === "number" ? options.minPassRate : 1.0;
21
+ const timeoutMs = options.timeoutMs || 30000;
22
+
23
+ const runs = [];
24
+ let passes = 0;
25
+ let failures = 0;
26
+ const startTime = Date.now();
27
+
28
+ for (let i = 1; i <= repeat; i++) {
29
+ const runStart = Date.now();
30
+ let pass = false;
31
+ let exitCode = 0;
32
+ let stdout = "";
33
+ let stderr = "";
34
+
35
+ try {
36
+ const env = { ...process.env };
37
+ for (const k of Object.keys(env)) {
38
+ if (k.startsWith("NODE_TEST_") || k.startsWith("NODE_CHANNEL_")) {
39
+ delete env[k];
40
+ }
41
+ }
42
+
43
+ stdout = execSync(cmd, {
44
+ cwd: root,
45
+ env,
46
+ timeout: timeoutMs,
47
+ stdio: ["ignore", "pipe", "pipe"],
48
+ encoding: "utf-8",
49
+ });
50
+ pass = true;
51
+ passes++;
52
+ } catch (err) {
53
+ exitCode = err.status || 1;
54
+ stdout = err.stdout ? String(err.stdout) : "";
55
+ stderr = err.stderr ? String(err.stderr) : err.message;
56
+ failures++;
57
+ }
58
+
59
+ const duration = Date.now() - runStart;
60
+ runs.push({
61
+ iteration: i,
62
+ pass,
63
+ exitCode,
64
+ durationMs: duration,
65
+ stdout: stdout.slice(0, 500),
66
+ stderr: stderr.slice(0, 500),
67
+ });
68
+ }
69
+
70
+ const passRate = passes / repeat;
71
+ const oscillation = computeOscillation(runs.map((r) => r.pass));
72
+ const totalDuration = Date.now() - startTime;
73
+ const ok = passRate >= minPassRate && (failures === 0 || oscillation === 0);
74
+
75
+ return {
76
+ ok,
77
+ repeat,
78
+ passes,
79
+ failures,
80
+ passRate: Math.round(passRate * 100) / 100,
81
+ oscillation: Math.round(oscillation * 100) / 100,
82
+ runs,
83
+ durationMs: totalDuration,
84
+ summary: `Stability Probe: ${passes}/${repeat} passed (${Math.round(passRate * 100)}% pass rate, oscillation: ${oscillation})`,
85
+ };
86
+ }
@@ -685,6 +685,178 @@ The test must fail on a hand-broken fixture before you consider it done.`;
685
685
  4. **Regression Verification**:
686
686
  - Ensure 100% of existing and new tests pass cleanly with zero errors.`;
687
687
  }
688
+ },
689
+
690
+ // ---------------------------------------------------------------------------
691
+ // Universal / stack-agnostic templates.
692
+ //
693
+ // The earlier templates were written for web frontends and Node projects, but
694
+ // `agentctl init` runs in Rust, Go, Python, PHP, .NET, Java, Ruby and Elixir
695
+ // repositories too. A template whose verification oracle is "npm test" or
696
+ // "npx lhci" is useless in a Cargo or pyproject checkout. Each template below
697
+ // therefore:
698
+ // - names no specific package manager, framework or language in its prompt;
699
+ // - defaults defaultVerifyCmd to the placeholder "npm test" ONLY because
700
+ // synthesizeWebEnvelope lets the caller (planTaskCreate) override it from
701
+ // config.verify.test, which the stack detector already resolved — so a
702
+ // Rust repo dispatches `cargo test` here without the prompt ever naming
703
+ // it; and
704
+ // - carries a real, locally-falsifiable oracle rather than a "best practice"
705
+ // claim no test can exercise.
706
+ // ---------------------------------------------------------------------------
707
+
708
+ "agent-dep-audit": {
709
+ id: "agent-dep-audit",
710
+ name: "Dependency & Supply-Chain Integrity Audit",
711
+ description: "Audit lockfile integrity, pinning, and install-time scripts across any language's dependency manifest without contacting a vulnerability database.",
712
+ defaultVerifyCmd: "npm test",
713
+ category: "Supply Chain & Dependencies",
714
+ criticFocus: [
715
+ "Verify every declared dependency resolves to a pinned, checksummed artifact in the committed lockfile; no floating ranges, no branch/tag refs, no unpinned git/http sources.",
716
+ "Confirm no install/postinstall lifecycle script runs unchecked code, and that any such script is pinned to a version or audited inline rather than fetched at install time.",
717
+ "Check that the lockfile in the diff is the one the current manifest resolves to — a stale lockfile that does not satisfy the manifest fails the gate, not a warning.",
718
+ "Ensure newly added dependencies are actually imported by in-scope source; a dependency present in the manifest but unused by the codebase is bloat, not a requirement.",
719
+ "Do not fetch a CVE database or contact any advisory API from the verification step. The template verifies pinning and integrity, which is falsifiable offline; known-vulnerability triage is a separate human decision."
720
+ ],
721
+ defaultParams: {
722
+ manifestScope: "the project's dependency manifest and lockfile"
723
+ },
724
+ generatePrompt: (params = {}) => {
725
+ const scope = params.manifestScope || "the project's dependency manifest and lockfile";
726
+ const customGoal = params.goal ? `\n- **Target Focus**: ${params.goal}` : "";
727
+
728
+ return `Audit dependency and supply-chain integrity for ${scope}.${customGoal}
729
+
730
+ ### Supply-Chain Integrity Invariants:
731
+ 1. **Pinned, Checksummed Resolution**:
732
+ - Every direct and transitive dependency in the manifest must resolve to an exact, checksummed entry in the committed lockfile. No floating version ranges, no branch or tag refs, no unpinned VCS sources.
733
+ - If the project uses a lockfile format that records hashes, verify each newly added or changed entry carries its expected integrity hash.
734
+ 2. **Stale Lockfile Gate**:
735
+ - The lockfile in the diff must satisfy the manifest as it stands after the change. A lockfile that no longer resolves the declared requirements fails the audit; do not regenerate it as part of an unrelated change.
736
+ 3. **Install-Time Script Scrutiny**:
737
+ - Enumerate every lifecycle / postinstall / build script that executes on install. Each one must either be unnecessary (and removed), pinned to a fixed version, or audited inline with a one-line justification in the PR.
738
+ 4. **Reachability, Not Hoarding**:
739
+ - A newly added dependency must be imported by in-scope source. If it is present in the manifest but no source references it, remove it.
740
+ 5. **Offline Verification Oracle**:
741
+ - Add or extend a repository-local check that the manifest and lockfile agree (a lockfile-staleness assertion using the project's own tooling, e.g. \`pip install --dry-run\`, \`cargo verify-project\`, \`go mod verify\`, \`bundle check\`, or an equivalent for the detected stack). It must run without network access and fail on a hand-broken fixture.`;
742
+ }
743
+ },
744
+
745
+ "agent-doc-drift": {
746
+ id: "agent-doc-drift",
747
+ name: "Documentation & Command-Surface Drift Audit",
748
+ description: "Cross-check documented commands, flags, environment variables and SDK exports against the actual CLI/SDK surface, fixing or deleting stale references.",
749
+ defaultVerifyCmd: "npm test",
750
+ category: "Docs & Maintenance",
751
+ criticFocus: [
752
+ "Verify every documented CLI subcommand, flag and exit code exists in the actual command parser; a README example referencing a removed flag is a defect, not a cosmetic issue.",
753
+ "Check that environment variables named in docs and .env.example are actually read by source, and that every variable source reads is documented — undocumented configuration is a trap for the next operator.",
754
+ "Confirm public SDK exports listed in docs match what the package entry point actually exports; a documented symbol that does not exist breaks a consumer on upgrade.",
755
+ "Prefer deleting a stale claim over weakening it. If a feature was removed, remove its documentation; do not leave a paragraph that hedges around it.",
756
+ "Paste the diff of the command/flag/export inventory the audit was based on, so the claim is reproducible rather than asserted."
757
+ ],
758
+ defaultParams: {
759
+ docScope: "README, docs/, and inline command help"
760
+ },
761
+ generatePrompt: (params = {}) => {
762
+ const scope = params.docScope || "README, docs/, and inline command help";
763
+ const customGoal = params.goal ? `\n- **Target Focus**: ${params.goal}` : "";
764
+
765
+ return `Audit ${scope} for drift against the actual command surface, configuration and public SDK, and correct every confirmed mismatch.${customGoal}
766
+
767
+ ### Documentation Drift Invariants:
768
+ 1. **Command & Flag Inventory**:
769
+ - Enumerate every subcommand, flag, positional argument and exit code the CLI parser actually defines. Compare it against every code block in the documentation that invokes the tool.
770
+ - A documented command that errors with \"unknown command\" or \"unknown flag\" fails the audit. Fix the doc or the parser — but do not silently add a flag just to satisfy a stale example.
771
+ 2. **Configuration Parity**:
772
+ - Every environment variable or config key the source reads must appear in the documented configuration reference and, where applicable, in \`.env.example\`.
773
+ - Every variable listed in \`.env.example\` or the config reference must be read somewhere in source. Entries that name a variable nothing reads are stale.
774
+ 3. **Public Surface Parity**:
775
+ - For a library, every export named in the API reference must be importable from the package entry point. Every exported, documented symbol must still exist.
776
+ 4. **Delete, Don't Hedge**:
777
+ - When a feature was removed, delete its documentation rather than leaving a paragraph that hedges or says \"formerly\". A reader who was never going to use it does not need its history.
778
+ 5. **Evidence**:
779
+ - Attach the inventory (commands, env vars, exports) the audit compared against. A claim that \"the docs are in sync\" without the underlying list is not a result.`;
780
+ }
781
+ },
782
+
783
+ "agent-config-audit": {
784
+ id: "agent-config-audit",
785
+ name: "Configuration, Defaults & Secret-Hygiene Audit",
786
+ description: "Audit configuration loading, default safety, and secret handling across any stack — env vars, config files, and secret redaction in logs.",
787
+ defaultVerifyCmd: "npm test",
788
+ category: "Security & Operations",
789
+ criticFocus: [
790
+ "Verify every configuration value has a safe default or fails closed with an actionable error; a missing required value must never silently become undefined, an empty string, or 'true'.",
791
+ "Confirm no secret is logged at any level — including debug — and that error messages, stack traces and telemetry redact tokens, passwords and connection strings before they are emitted.",
792
+ "Check that boolean/number config is parsed into its type, not passed through as a string that only happens to be truthy; 'false' as a string is a classic fail-open.",
793
+ "Ensure .env or equivalent secret files are gitignored, that .env.example contains no real values, and that the audit does not itself commit a secret to prove the gate works.",
794
+ "Do not weaken the secret scanner to silence a finding; remove the secret and rotate it if it was ever committed."
795
+ ],
796
+ defaultParams: {
797
+ configScope: "application configuration and environment loading"
798
+ },
799
+ generatePrompt: (params = {}) => {
800
+ const scope = params.configScope || "application configuration and environment loading";
801
+ const customGoal = params.goal ? `\n- **Target Focus**: ${params.goal}` : "";
802
+
803
+ return `Audit ${scope} for safe defaults, typed loading, and secret hygiene.${customGoal}
804
+
805
+ ### Configuration & Secret Invariants:
806
+ 1. **Safe Defaults, Fail-Closed Required Values**:
807
+ - Every configuration key must either have an explicitly documented safe default, or fail closed at load time with an actionable error naming the missing variable.
808
+ - Never let a missing required value degrade to \`undefined\`, an empty string, or a truthy string that masks the misconfiguration.
809
+ 2. **Typed Loading**:
810
+ - Parse booleans, numbers and durations into their types. A string \`\"false\"\` is truthy in most languages; a config that compares it against the boolean \`false\` fails open.
811
+ - Reject unknown or misspelled keys rather than silently ignoring them — a typo in an env var name otherwise looks like a default.
812
+ 3. **Secret Hygiene in Logs & Errors**:
813
+ - No secret may appear in a log line at any level, including debug. Redact tokens, passwords, API keys and connection strings in error messages, stack traces and telemetry payloads before they are emitted.
814
+ - Verify redaction by triggering a representative error path and asserting the output does not contain the configured secret value.
815
+ 4. **Secret Files Stay Out of Version Control**:
816
+ - Confirm \`.env\` and equivalent secret-bearing files are ignored by version control, and that the example/template file contains no real credentials — only placeholders.
817
+ - If the audit finds a committed secret, the fix is to remove it and rotate the credential, not to relax the scanner.
818
+ 5. **Falsifiable Oracle**:
819
+ - Add a test that loads config with a missing required value and asserts it fails closed; and a test that a representative secret is redacted from a logged error. Both must fail before the fix and pass after.`;
820
+ }
821
+ },
822
+
823
+ "agent-api-contract": {
824
+ id: "agent-api-contract",
825
+ name: "API Contract & Error-Code Consistency Audit",
826
+ description: "Audit request/response handlers against their declared routes, schemas and error codes — universal across REST, GraphQL and RPC surfaces.",
827
+ defaultVerifyCmd: "npm test",
828
+ category: "API & Contracts",
829
+ criticFocus: [
830
+ "Verify every declared route/RPC method has a registered handler, and every registered handler is reachable through a declared route — orphaned handlers and unhandled routes are both defects.",
831
+ "Confirm request bodies, query params and path params are validated against a declared schema before reaching handler logic; unvalidated input is the root cause the schema exists to prevent.",
832
+ "Check that error responses share a single documented shape ({ ok, code, error } or the stack's convention) and that no handler leaks a stack trace, internal path, or upstream error body to the caller.",
833
+ "Ensure success and error status codes are consistent across the surface — a 200 with { error: ... } body or a 500 for a validation failure both break contract-aware clients.",
834
+ "Do not weaken a test to accept an inconsistent response; fix the handler or the contract so they agree."
835
+ ],
836
+ defaultParams: {
837
+ apiScope: "the HTTP/RPC API surface"
838
+ },
839
+ generatePrompt: (params = {}) => {
840
+ const scope = params.apiScope || "the HTTP/RPC API surface";
841
+ const customGoal = params.goal ? `\n- **Target Focus**: ${params.goal}` : "";
842
+
843
+ return `Audit ${scope} for route/handler parity, input validation and a consistent error contract.${customGoal}
844
+
845
+ ### API Contract Invariants:
846
+ 1. **Route/Handler Parity**:
847
+ - Enumerate every declared route, method or RPC operation and confirm it resolves to a registered handler. Enumerate every registered handler and confirm it is reachable through a declared route.
848
+ - An orphaned handler is dead code; an unhandled declared route is a 404/501 waiting to happen. Both fail the audit.
849
+ 2. **Input Validation at the Boundary**:
850
+ - Every request body, query parameter and path parameter must be validated against a declared schema before it reaches handler logic. Reject unknown fields rather than silently dropping them.
851
+ - Validation failures must return the documented client-error status (typically 4xx), never a 500, and must name the offending field.
852
+ 3. **One Error Shape, No Leaks**:
853
+ - Every error response must use the project's single documented error shape (for example \`{ ok: false, code, error }\`). No handler may emit a different ad-hoc shape.
854
+ - Never return a stack trace, filesystem path, upstream credential, or raw upstream error body to the caller. Log those server-side and return a stable, documented error code.
855
+ 4. **Status-Code Consistency**:
856
+ - Success responses use the appropriate 2xx/3xx; client errors use 4xx; server errors use 5xx. A 200 with an \`error\` field, or a 500 for a bad request, breaks every contract-aware client.
857
+ 5. **Contract Test Oracle**:
858
+ - Add or extend a table-driven test that, for each route in the inventory, asserts: the route resolves to a handler, an invalid payload returns the documented 4xx shape, and an unauthenticated/unauthorized request returns the documented status without a body leak. The test must fail on a hand-introduced orphan route or a leaking error before the fix.`;
859
+ }
688
860
  }
689
861
  };
690
862
 
@@ -1 +0,0 @@
1
- export * from "./asset-integrity.mjs";
@@ -1 +0,0 @@
1
- export * from "./execution-envelope.mjs";
@@ -1 +0,0 @@
1
- export * from "./rules-budget.mjs";