jules-orchestrator-kit 0.72.3 → 0.73.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.
- package/.agent/prompts/{Overseer.md → Auditor.md} +3 -3
- package/.agent/prompts/{Alchemist.md → Database.md} +1 -1
- package/.agent/prompts/Debugger.md +25 -0
- package/.agent/prompts/{Scribe.md → Docs.md} +8 -5
- package/.agent/prompts/{Spectator.md → E2E.md} +9 -6
- package/.agent/prompts/{Janitor.md → Hygiene.md} +2 -2
- package/.agent/prompts/{Bolt.md → Performance.md} +1 -1
- package/.agent/prompts/Resilience.md +20 -0
- package/.agent/prompts/Security.md +21 -0
- package/.agent/prompts/Testing.md +30 -0
- package/.agent/prompts/Types.md +19 -0
- package/.agent/rules/jules-protocol.md +5 -37
- package/CHANGELOG.md +197 -23
- package/JULES_RULES_TEMPLATE.md +45 -123
- package/LICENSE +1 -1
- package/README.md +143 -471
- package/bin/agentctl.mjs +437 -143
- package/bin/init.js +6 -3
- package/index.mjs +9 -6
- package/package.json +3 -5
- package/scripts/asset-integrity-check.mjs +1 -1
- package/scripts/doc-sync-check.mjs +32 -0
- package/scripts/generate-command-reference.mjs +39 -0
- package/scripts/jules-dispatch.mjs +12 -113
- package/scripts/jules-merge-swarm.mjs +8 -196
- package/scripts/jules-patch.mjs +7 -8
- package/scripts/jules-queue-runner.mjs +6 -8
- package/scripts/jules-scan-todos.mjs +10 -38
- package/scripts/jules-self-audit.mjs +8 -139
- package/scripts/jules-status.mjs +32 -38
- package/scripts/jules-webhook-receiver.mjs +1 -1
- package/src/assertions.mjs +5 -50
- package/src/bidi-guard.mjs +36 -0
- package/src/budget.mjs +3 -14
- package/src/config.mjs +2 -6
- package/src/dashboard.mjs +7 -9
- package/src/dispatch.mjs +212 -0
- package/src/engine.mjs +41 -17
- package/src/evidence.mjs +10 -41
- package/src/execution-envelope.mjs +13 -1
- package/src/flaky-ledger.mjs +1 -1
- package/src/fs-atomic.mjs +72 -0
- package/src/git.mjs +298 -27
- package/src/mcp.mjs +290 -3
- package/src/memory.mjs +5 -1
- package/src/merge-swarm.mjs +202 -0
- package/src/ops/cli-intent.mjs +1 -0
- package/src/ops/command-registry.mjs +796 -70
- package/src/ops/doctor-registry.mjs +134 -47
- package/src/ops/handover.mjs +3 -27
- package/src/ops/pr-harvest.mjs +1 -1
- package/src/prompt-guard.mjs +27 -3
- package/src/provider.mjs +51 -7
- package/src/remediation.mjs +2 -2
- package/src/review-repair.mjs +1 -2
- package/src/role-resolver.mjs +113 -3
- package/src/router.mjs +19 -11
- package/src/runtime-env.mjs +67 -0
- package/src/scaffold.mjs +3 -1
- package/src/scope-guard.mjs +249 -0
- package/src/secret-scanner.mjs +530 -0
- package/src/security.mjs +79 -2971
- package/src/self-audit.mjs +140 -0
- package/src/session-ops.mjs +30 -1
- package/src/stability.mjs +8 -1
- package/src/state.mjs +45 -0
- package/src/swarm.mjs +76 -0
- package/src/task-optimizer.mjs +1 -1
- package/src/telemetry.mjs +23 -0
- package/src/test-tamper-guard.mjs +2173 -0
- package/src/todo-scanner.mjs +129 -0
- package/src/web-templates.mjs +3 -3
- package/src/webhook.mjs +10 -3
- package/src/wizard-init.mjs +12 -20
- package/src/wizard-task.mjs +38 -11
- package/.agent/prompts/Sentinel.md +0 -18
- package/AGENTS.md +0 -135
- package/ROADMAP_V1.md +0 -257
- package/scripts/utils.mjs +0 -241
package/CHANGELOG.md
CHANGED
|
@@ -5,8 +5,69 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.73.1] - 2026-09-17
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Consolidated contributor instructions in `AGENTS.md` and shortened the installed
|
|
14
|
+
rules template while preserving scaffold detection and existing file paths.
|
|
15
|
+
- Reworked onboarding, moved Jules guidance to provider documentation and archived
|
|
16
|
+
historical audits. Simplified the roadmap and removed release-note epigraphs.
|
|
17
|
+
- Excluded repository-only `AGENTS.md` and `ROADMAP_V1.md` from the npm payload;
|
|
18
|
+
retained runtime modules, script entry points and scaffold assets.
|
|
19
|
+
- Clarified rerunning `init` in initialized repositories: back up and review
|
|
20
|
+
`.agent/config.yml` and `.agent/jules.yml` because the wizard can regenerate them.
|
|
21
|
+
- Added deterministic review planning as a later roadmap candidate while keeping AI
|
|
22
|
+
review advisory and separate from the deterministic `gate`.
|
|
23
|
+
|
|
24
|
+
## [0.73.0] - 2026-09-09
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- **CLI Command Registry & Auto-Generated Documentation (P06) (`src/ops/command-registry.mjs`, `docs/COMMAND_REFERENCE.md`)**: Reconciled all 49 CLI commands and flags with a single source of truth registry. Added `agentctl help <cmd>`, interactive wizard routing, and automated generation and doc-sync validation of `docs/COMMAND_REFERENCE.md`.
|
|
28
|
+
- **Documentation Architecture & Sitemap (P10) (`docs/README.md`, `docs/configuration.md`, `docs/sdk.md`, `docs/uninstall.md`)**: Reorganized documentation into modular reference guides linked from a unified sitemap, and streamlined `README.md` to under 200 lines.
|
|
29
|
+
- **Contributor Provenance & Attribution (P13) (`CONTRIBUTORS.md`, `CONTRIBUTING.md`)**: Formalized maintainer and autonomous agent attribution (82 human maintainer commits, 366 autonomous coding agent commits) with conventional commits and release gates documentation.
|
|
30
|
+
- **Cold-Start Onboarding Hardening (P12) (`docs/cold-start-trial.md`, `src/git.mjs`, `src/ops/doctor-registry.mjs`, `src/wizard-task.mjs`)**: Filtered untracked root package artifacts during task creation on newly initialized repos, updated `init` commit hints to include package files, and made `agentctl doctor` red-flag missing verification oracles when verification is required.
|
|
31
|
+
- **Trojan Source BiDi Override Detection (PR #23) (`src/security.mjs`, `test/trojan-source.test.mjs`)**: Implemented `checkTrojanSource` to detect invisible Unicode bidirectional control characters (`U+202A`–`U+202E`, `U+2066`–`U+2069`, `U+061C`, `U+200E`, `U+200F`) on added code lines in diffs (CVE-2021-42574). Wired into `scanDiff` to emit a `CRITICAL` finding (`TROJAN_SOURCE_DETECTED`) for source files while exempting markdown documentation.
|
|
32
|
+
- **Positional Task Envelope & Queue Auto-Selection Dispatch (`bin/agentctl.mjs`)**: `agentctl dispatch` now accepts positional task envelope paths (e.g. `.agent/jules-queue/TASK-123.md` or `TASK-123`), automatically inherits embedded metadata defaults (title, role, tier, verification command, and flags) via `parseEnvelopeHeader`, and auto-consumes the next pending queue task when invoked without arguments. Dispatched queue tasks are automatically moved to `.agent/jules-queue/completed/` upon successful execution.
|
|
33
|
+
- **Testing Specialist Role (`.agent/prompts/Testing.md`, `src/role-resolver.mjs`)**: Added canonical `testing` role (with aliases `test`, `unit-test`, `integration-test`, `qa`) dedicated to unit and integration test quality, negative-path coverage, deterministic fixtures, state isolation, and mutation sensitivity without test weakening.
|
|
34
|
+
- **Session List CLI & Remote Enumeration (`bin/agentctl.mjs`, `src/ops/command-registry.mjs`)**: Added `agentctl session list` (and `agentctl sessions`) with support for `--limit`, `--remote`, `--dry-run`, and `--json`, enabling inspection of recent and active Jules sessions across remote API endpoints and local ledgers.
|
|
35
|
+
- **Unattended Dispatch Flag (`bin/agentctl.mjs`, `src/ops/command-registry.mjs`)**: Added `--auto-approve-plans` and `--auto-approve` flags to `agentctl dispatch`, allowing autonomous runs to disable manual plan approval requirements (`requirePlanApproval: false`).
|
|
36
|
+
- **MCP Session Lifecycle Tools & Resources (`src/mcp.mjs`)**: Added `jules_approve_plan`, `jules_send_message`, and `jules_wait_for_session` tools (20 total MCP tools) alongside `jules://status`, `jules://sources`, and `jules://sessions` MCP resources.
|
|
37
|
+
- **Debugger Specialist Role & Precondition Verification Protocol (`.agent/prompts/Debugger.md`, `.agent/prompts/E2E.md`)**: Added dedicated `debugger` role for failure localization and root-cause analysis without modifying test assertions, and codified "Verify before you block" precondition checking for end-to-end tests.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
- **Security Module Split (P05) (`src/security.mjs`, `src/fs-atomic.mjs`, `src/scope-guard.mjs`, `src/secret-scanner.mjs`, `src/test-tamper-guard.mjs`, `src/bidi-guard.mjs`)**: The 3,425-line `src/security.mjs`, which bundled five responsibilities, is now a facade over five focused submodules — atomic filesystem writes, scope policy and the regex-free glob matcher, credential/PII detection, test-tamper detection with its multi-language statement parser, and Trojan Source BiDi detection. `scanDiff()` remains in the facade as the orchestrator that walks the diff once and calls them. Pure relocation: no regex, signature, or control flow changed, and the facade re-exports all 26 public symbols so every existing `import … from "./src/security.mjs"` path and every `index.mjs` export still resolves to the same object. The 59-canary `guard-reach` activation gate stays red-if-silenced across the new module boundaries.
|
|
41
|
+
- **Role Prompt Consolidation & One-Directional Aliases (P03) (`.agent/prompts/`, `src/role-resolver.mjs`)**: Deleted the 9 legacy duplicate prompt files after porting their unique instructions into the canonical roles; `.agent/prompts/` now holds exactly the 12 canonical roles plus `Task_Template.md`. `ROLE_ALIASES` is strictly one-directional (legacy/shortcut → canonical) with the reverse map moved to a private on-disk fallback so pre-consolidation checkouts keep resolving.
|
|
42
|
+
- **Audit Ledger Bypass Closed (P04) (`src/budget.mjs`, `src/state.mjs`, `test/budget-ledger.test.mjs`)**: Closed verification bypass where missing daily budget ledgers were silently skipped; retired legacy `scripts/utils.mjs` shim and relocated core business logic into `src/`.
|
|
43
|
+
- **Security Invariants & Threshold Grounding (P09) (`SECURITY.md`)**: Corrected Shannon entropy thresholds (`> 3.6` bits/char for environment variables, `> 4.5` bits/char for base64/hex tokens) and accurately documented execution envelope parameters and ledger chain verification.
|
|
44
|
+
- **Test Archaeology & Domain Suite Consolidation (P08) (`test/`)**: Consolidated 16 scattered audit-trial test files into 4 domain-focused suites (`cli-surface.test.mjs`, `budget-ledger.test.mjs`, `tamper-detection.test.mjs`, `provider-failover.test.mjs`), expanding test coverage to 1,530 passing unit tests across 204 suites.
|
|
45
|
+
- **Cross-Platform CRLF Normalization**: Normalized line endings across Windows, Linux, and macOS in reference generators and doc-sync gates.
|
|
46
|
+
- **Router Role Normalization & Tier Alignment (`src/router.mjs`)**: Normalized requested roles via `ROLE_ALIASES` so canonical roles route identically to legacy aliases: `security` forces complex tier, `auditor` leans complex, and `hygiene` / `performance` lean fast.
|
|
47
|
+
- **Dispatch Idempotency & Final Payload Ceiling (`src/engine.mjs`)**: Idempotent role injection prevents duplicate specialist prompt headers, preserves role/memory context when `taskInstructions` is present, propagates active config overrides to role hydration, and validates the assembled final prompt against `limits.promptKb`.
|
|
48
|
+
- **Code Block & Inline Backtick Preservation in Vocabulary Sanitizer (`src/prompt-guard.mjs`)**: `sanitizePromptVocabulary` now preserves fenced code blocks and inline backtick code spans verbatim, preventing alteration of exact technical commands, signals (`SIGKILL`), and identifiers.
|
|
49
|
+
- **Task Objective Preflight Validation (`src/wizard-task.mjs`)**: `planTaskCreate` now enforces that a concrete task objective or template is provided before injecting role instructions, preventing creation of empty tasks with only role descriptions.
|
|
50
|
+
- **Two-Hop Legacy Alias Resolution (`src/role-resolver.mjs`)**: Shortcuts like `perf` now map through canonical `performance` to legacy `Bolt.md` in legacy-only checkouts.
|
|
51
|
+
- **Mutation Template Invariant (`src/web-templates.mjs`)**: In `agent-qa-mutation`, replaced the directive to delete surviving tests with a mandate to add targeted assertions and classify equivalent mutants, strictly forbidding test deletion.
|
|
52
|
+
- **Specialist Prompts Hardening (`.agent/prompts/`)**: Clarified retry and fallback semantics in `Resilience.md`, decoupled secret mechanisms from Node-specific `process.env` in `Security.md`, forbade permissive coercions and casts in `Types.md`, and expanded `Docs.md` to cover technical documentation, API references, and CLI manuals.
|
|
53
|
+
- **Engineering Role Professionalization & Aliases (`src/role-resolver.mjs`, `.agent/prompts/`)**: Replaced fantasy/RPG nomenclature across all 12 specialist roles (`Bulwark` $\rightarrow$ `resilience`, `Alchemist` $\rightarrow$ `database`, `Janitor` $\rightarrow$ `hygiene`, `Sentinel` $\rightarrow$ `security`, `Bolt` $\rightarrow$ `performance`, `Spectator` $\rightarrow$ `e2e`, `Overseer` $\rightarrow$ `auditor`, `Typist` $\rightarrow$ `types`, `Scribe` $\rightarrow$ `docs`, `Hunter` $\rightarrow$ `debugger`, `Testing`, `a11y` $\rightarrow$ `a11y`). Stripped emojis and colloquial prose, while maintaining complete backward compatibility via `ROLE_ALIASES` for CLI flags, dispatches, and configs.
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
- **Dashboard Port Range Validation & Consensus (D1, D2, D3) (`bin/agentctl.mjs`, `src/dashboard.mjs`, `src/ops/command-registry.mjs`, `README.md`)**: Supported both positional `agentctl dashboard <port>` and `--port <port>` syntax, added 1024–65535 port range validation with clean exit code 1 errors on invalid input instead of unhandled exceptions, ensured `createDashboardServer` honors configured ports, and unified default port consensus at 4100 across the CLI, command registry, and documentation.
|
|
57
|
+
- **Dynamic Guardrails Word Boundaries & File Loading (D4, D5, D6) (`src/dispatch.mjs`, `scripts/jules-dispatch.mjs`, `.agent/rules/dynamic-guardrails.json`)**: Loaded custom project rules dynamically from `.agent/rules/dynamic-guardrails.json`, enforced strict regex word boundaries (`\bsec\b`, `\bkey\b`, `\bauth\b`) to eliminate false-positive activations on words like "breakfast" or "sector", and updated trigger labels to canonical specialist role identifiers.
|
|
58
|
+
- **Preflight Static Manifest & Syntax Validation (D7) (`src/dispatch.mjs`, `scripts/jules-dispatch.mjs`)**: Replaced unconditional `"PASSED"` stub in `runPreflightStaticCheck` with verification of `package.json` existence and JSON object parse integrity, failing closed when manifests are missing or malformed.
|
|
59
|
+
- **Sterile Process Management Vocabulary Case Sensitivity (D8) (`src/prompt-guard.mjs`, `test/prompt-guard.test.mjs`)**: Added `/i` flag to `/\bSIGKILL\b/gi` in `STERILE_VOCABULARY_MAP`, ensuring clinical process term substitution catches lowercase and mixed-case process termination tokens.
|
|
60
|
+
- **TODO Scanner Safety Limits & Gitignore Exclusions (D9) (`src/todo-scanner.mjs`, `scripts/jules-scan-todos.mjs`)**: Enforced safe traversal bounds on `agentctl scan` by restricting scanning to source extensions (`.js`, `.mjs`, `.ts`, `.py`, `.rs`, `.go`, `.md`), imposing a 1 MB per-file size ceiling, skipping binary buffers with null bytes, and honoring root `.gitignore` exclude patterns.
|
|
61
|
+
- **Dispatch Argv Scope Isolation (D10) (`src/dispatch.mjs`, `scripts/jules-dispatch.mjs`)**: Moved CLI argument parsing inside the execution entry guard (`process.argv[1]`), preventing module importers from prematurely consuming or baking global `process.argv` into function defaults.
|
|
62
|
+
- **Dashboard Manifest Read Deduplication (D11) (`src/dashboard.mjs`)**: Replaced redundant `readFileSync` of `package.json` in the dashboard server with imported `KIT_VERSION`.
|
|
63
|
+
- **Composite GitHub Action API Key Input (D12) (`.github/actions/setup-jules/action.yml`)**: Parameterized `jules_api_key` as an explicit action input defaulting to `${{ secrets.JULES_API_KEY }}`, preventing silent authentication failures caused by unpopulated composite `env:` blocks.
|
|
64
|
+
- **Asset Integrity Scanner Non-Vacuous Status Reporting (D13) (`src/asset-integrity.mjs`, `scripts/asset-integrity-check.mjs`)**: Returned explicit `status: N/A` when no asset directories exist, and verified fail-closed detection when corrupt image headers are encountered.
|
|
65
|
+
- **Specialist Role Consolidation & One-Directional Aliases (D14, D15) (`.agent/prompts/`, `src/role-resolver.mjs`)**: Deleted 9 legacy duplicate role prompt files after porting unique domain directives into 12 canonical roles, and made `ROLE_ALIASES` strictly one-directional (legacy $\rightarrow$ canonical) with private fallback for historical checkouts.
|
|
66
|
+
- **Balanced Swarm Slot Partitioning (D16) (`src/dispatch.mjs`, `scripts/jules-dispatch.mjs`)**: Replaced unbalanced slot partitioning with `getAlphaRange`, partitioning A–Z into contiguous letter ranges differing by at most one character for arbitrary slot counts $N > 2$.
|
|
67
|
+
- **Execution Envelope Config Scope Hashing (D17) (`src/execution-envelope.mjs`, `test/execution_envelope.test.mjs`)**: Aligned `configSha` generation to hash `{ denyPaths, allowPaths, protectPaths }` consistently, establishing tamper-evident config scope tracking across envelopes.
|
|
68
|
+
- **Environment Tier Specification & Preset Parity (D18) (`.env.example`, `src/config.mjs`, `test/config_tier.test.mjs`)**: Documented `JULES_TIER` (`free` | `pro` | `ultra`) in `.env.example` and verified parity between `TIER_PRESETS` and vendor tier specifications.
|
|
69
|
+
|
|
8
70
|
## [0.72.3] - 2026-09-08
|
|
9
|
-
*A directive not understood is silence; a tag not stripped is a backdoor.*
|
|
10
71
|
|
|
11
72
|
Hardens prompt boundaries against Unicode Tag ASCII smuggling, expands clinical vocabulary to mitigate Vertex AI false-positive aborts, injects deep planning directives, and grounds runtime VM/cgroup constraints:
|
|
12
73
|
- **Unicode Tag Plane & ASCII Smuggling Defense (`src/prompt-guard.mjs`, `src/security.mjs`)**: Gemini Pro tokenizes invisible Unicode Tag characters (`U+E0000` to `U+E007F`) as operational ASCII tokens. Both `ZERO_WIDTH_AND_BIDI_REGEX` and `INVISIBLE_CHARS` now strip and scan Plane 14 tag characters (`[\u{E0000}-\u{E007F}]`), preventing hidden prompt injections in GitHub issues/PR comments and credential hiding in diffs.
|
|
@@ -15,7 +76,6 @@ Hardens prompt boundaries against Unicode Tag ASCII smuggling, expands clinical
|
|
|
15
76
|
- **Grounded VM & cgroup Invariant Documentation (`.agent/rules/jules-protocol.md`)**: Formally documented KVM sandbox boundaries: Ubuntu 24.04.2 LTS (`x86_64`), cgroup v2 hard limit 8 GiB RAM with zero swap (`memory.swap.max = 0`), 20–30 GiB OverlayFS writable quota, `/workspace` repo mount, headless supervisor init (no systemd), and the three-source startup ingestion hierarchy (Task Prompt, root `AGENTS.md`, and root `README.md`).
|
|
16
77
|
|
|
17
78
|
## [0.72.2] - 2026-09-08
|
|
18
|
-
*A test suite that writes to stderr did not write silence.*
|
|
19
79
|
|
|
20
80
|
Fixes stream preservation in child process execution, stack-detection build defaults, and CLI flag parity uncovered during Bun + TypeScript trial execution:
|
|
21
81
|
- **Child Process Stream Fidelity & Stderr Preservation (`src/git.mjs`)**: `runCmd()` used `execSync`/`execFileSync` which hardcoded `stderr: ""` on zero exit status. Test runners that print progress and summary statistics to `stderr` (notably `bun test`) had their results silenced, causing `parseCollectedTests` to report unverified test counts. `runCmd()` now invokes `spawnSync` natively, capturing both `stdout` and `stderr` streams regardless of exit status.
|
|
@@ -23,7 +83,6 @@ Fixes stream preservation in child process execution, stack-detection build defa
|
|
|
23
83
|
- **CLI Ergonomics & Alias Parity (`bin/agentctl.mjs`)**: Added `--verify` as a first-class alias for `--verify-cmd` across `agentctl task create`, `task template`, and `task optimize`.
|
|
24
84
|
|
|
25
85
|
## [0.72.1] - 2026-09-08
|
|
26
|
-
*A diff cannot judge what it cannot see.*
|
|
27
86
|
|
|
28
87
|
Fixes staged-mode diff extraction and cross-language dead-guard detection uncovered during polyglot trial execution on Python/Make repositories:
|
|
29
88
|
- **Staged Mode Diff Fidelity (`src/git.mjs`)**: `diffText(root, base, "staged")` failed to query the git index, falling through to `git diff <base>...HEAD`. Consequently, staged modifications (`git add`) on feature branches were omitted from the diff passed to the secret scanner and anti-tamper guard. `diffText` now queries `git diff --cached <base>` in staged mode, ensuring cached index additions are fully inspected.
|
|
@@ -31,7 +90,6 @@ Fixes staged-mode diff extraction and cross-language dead-guard detection uncove
|
|
|
31
90
|
- **Assertion Coverage in Dead Conditions (`src/security.mjs`)**: `VACUOUS_ASSERTION` now detects both failure calls (`FAILURE_CALL`) and test assertions (`ASSERTION_PATTERN`) inside dead blocks.
|
|
32
91
|
|
|
33
92
|
## [0.72.0] - 2026-09-08
|
|
34
|
-
*A guard is not a policy if the diff under review can rewrite the rules.*
|
|
35
93
|
|
|
36
94
|
A fifth cold-start audit, against published v0.71.0 on four polyglot repositories (`p-limit`, `itsdangerous`, `is`, `mini_markdown`). Twenty-two findings across three tiers:
|
|
37
95
|
- Tier 1 (Security & Isolation): uncommitted scaffold tampering, untrusted working-tree configs in staged/committed evaluation, and unisolated snapshot leaks.
|
|
@@ -61,7 +119,6 @@ A fifth cold-start audit, against published v0.71.0 on four polyglot repositorie
|
|
|
61
119
|
- **Cold-Start Trial Regression Suites**: Added 52 new regression tests across `test/cold-start-trial-f01-f12.test.mjs`, `test/cold-start-trial-f06-f11.test.mjs`, and `test/cold-start-trial-f13-f22.test.mjs`.
|
|
62
120
|
|
|
63
121
|
## [0.71.0] - 2026-09-05
|
|
64
|
-
*A blanket is not a check, and silence is not a suite.*
|
|
65
122
|
|
|
66
123
|
A fourth cold-start trial, against v0.70.0 on four repositories nobody here chose. Seven findings, and this is the first trial where every one of them held: no quoted output was fabricated, and all four repository SHAs matched. Two of them prove entries in this file wrong, which is recorded below rather than quietly amended.
|
|
67
124
|
|
|
@@ -95,7 +152,6 @@ Two `### Not Reproduced` claims in **[0.69.0]** were wrong, and both were wrong
|
|
|
95
152
|
One finding in the fourth trial quoted output that does not reproduce: its `--allow-test-change expectation` case shows `APPROVED (Exit 0)`, where the run rejects at `Exit 4` because the reporter's own `sed` genuinely breaks the dotenv suite — the same fixture artefact this project has hit in every trial. The finding itself, that no override leaves a trace in the report, held and is fixed above.
|
|
96
153
|
|
|
97
154
|
## [0.70.0] - 2026-09-05
|
|
98
|
-
*A session that has not finished is not a session that passed.*
|
|
99
155
|
|
|
100
156
|
An audit of the Jules session layer against the API it talks to. Twelve findings, each traced to a file and line in `docs/jules-quality-plan.md`; the three below are the ones that let the kit believe something about a session that was not true.
|
|
101
157
|
|
|
@@ -112,7 +168,6 @@ An audit of the Jules session layer against the API it talks to. Twelve findings
|
|
|
112
168
|
- **A Non-Terminal Session Is Announced Before The Gate Runs (`src/engine.mjs`)**: the repair loop polled the session and discarded the answer, then ran re-verification against a tree the agent might not have finished writing. The verdict is now read: a non-terminal session prints `[SESSION_NOT_TERMINAL]` naming what it is waiting on and appends a `session_not_terminal` telemetry event. The gate still runs either way — it is the authority on whether the change works — but it no longer runs silently on a half-applied patch.
|
|
113
169
|
|
|
114
170
|
## [0.69.0] - 2026-09-04
|
|
115
|
-
*A denominator is not evidence if the things counted in it were never read.*
|
|
116
171
|
|
|
117
172
|
A third cold-start trial against v0.68.0. Twelve findings; six reproduced, and the two most serious were graded lower by the trial than they deserved. The pattern in both: the guard recognised a line as an assertion, counted it in `assertionsSeen`, and reported `PASS` without ever reading the value being asserted. `UNREADABLE` exists precisely so that "I could not read this" and "I read this and it is fine" look different — and a line could pass the readability test while its expectation stayed opaque.
|
|
118
173
|
|
|
@@ -142,7 +197,6 @@ Six of the twelve did not hold, and five quoted terminal output that does not ex
|
|
|
142
197
|
- **Eleven Cases In The Policy Contract (`src/guard-policy.mjs`)**: seven canaries for the expectation forms that were invisible — JUnit and PHPUnit expected-first, `assertIn`, `assertNotIn`, and regex patterns in `toMatch`, `toThrow` and RSpec `match` — and four innocent edits for the renames that were called tampering, plus JUnit 4's message-first form, which must stay silent. 42 canaries, 16 innocent edits.
|
|
143
198
|
|
|
144
199
|
## [0.68.0] - 2026-09-04
|
|
145
|
-
*A check that examined nothing does not get to say APPROVED.*
|
|
146
200
|
|
|
147
201
|
A second cold-start trial against v0.67.0, run as an unprimed stranger against the published package. Thirteen findings; eleven reproduced.
|
|
148
202
|
|
|
@@ -161,7 +215,6 @@ A second cold-start trial against v0.67.0, run as an unprimed stranger against t
|
|
|
161
215
|
Two findings did not reproduce against the shipped code. The assertion-message case (`assert enc == expect` → `assert enc == expect, "..."`) returns `PASS` on a real clone of `pallets/itsdangerous` running the reported command verbatim — and the transcript names a function, `test_int_to_bytes`, that the repository does not contain. The scaffold-exemption case does not collapse on an untracked file; it collapses on a *protected* one, such as a lockfile, which is the rule working as designed.
|
|
162
216
|
|
|
163
217
|
## [0.67.0] - 2026-09-04
|
|
164
|
-
*The last four from the trial, and the rule that a move is not a deletion.*
|
|
165
218
|
|
|
166
219
|
### Fixed
|
|
167
220
|
- **A Test Could Be Silenced With Its Own Standard Library (`src/security.mjs`)**: the decorator and annotation forms were covered — `@pytest.mark.skip`, `@Disabled`, `it.skip` — and the in-body call was not. Measured silent on six of seven: `self.skipTest()`, `pytest.skip()`, `raise unittest.SkipTest`, mocha's `this.skip()`, `test.todo()`, and Go's `t.SkipNow()` (`t.Skip(` was listed, but the pattern required the parenthesis immediately after the name). `self.skipTest()` is how unittest's own documentation writes it.
|
|
@@ -176,7 +229,6 @@ Two findings did not reproduce against the shipped code. The assertion-message c
|
|
|
176
229
|
This completes the cold-start trial: all twelve findings closed. Five more were found while reproducing them — a comment read as a line continuation, a message written outside the call, an argument walker that started one character early, line comments that `stripComments` had never stripped, and a test fixture that had left 18 GB in /tmp.
|
|
177
230
|
|
|
178
231
|
## [0.66.0] - 2026-09-04
|
|
179
|
-
*Saying nothing and saying approved must not look the same.*
|
|
180
232
|
|
|
181
233
|
### Fixed
|
|
182
234
|
- **An Assertion Is A Statement, Not A Line (`src/security.mjs`)**: the denominator counted `+`/`-` lines, so the commonest shape in every language with multi-line calls was invisible — `self.assertEqual(` on an unchanged context line, only its argument lines edited. Nothing among the changed lines matched an assertion pattern and nothing looked assertion-shaped, so a five-element expected list rewritten to one element to match broken output reported `assertionsSeen: 0` and a clean `PASS`. Measured on a real repository: five green phases and `APPROVED`. Detection missed it a second time even after the count was honest, because shape pairing compares statements with their literals blanked and a list that shrank lands in a different bucket; a new argument-level pass takes the arguments as the witness — same assertion, same arity, same *subject*, different expected value.
|
|
@@ -192,7 +244,6 @@ This completes the cold-start trial: all twelve findings closed. Five more were
|
|
|
192
244
|
The first three come from the cold-start trial's severity-1 findings. Two of them were defects in the mechanism built one release earlier to prevent exactly this class, which is the argument for having somebody else measure.
|
|
193
245
|
|
|
194
246
|
## [0.65.0] - 2026-09-04
|
|
195
|
-
*A gate that refuses its own installation is not strict, it is broken.*
|
|
196
247
|
|
|
197
248
|
Four failures from a cold-start trial on four public repositories nobody here chose. Every one of them meets a user before they have done anything, and every one was invisible to a suite measured in a repository that was already set up correctly by someone who knew how the tool worked.
|
|
198
249
|
|
|
@@ -209,7 +260,6 @@ Four failures from a cold-start trial on four public repositories nobody here ch
|
|
|
209
260
|
Found by a cold-start trial conducted as an unprimed stranger — install from the registry, `init` on four foreign stacks, then try to make the tool lie. Eleven of its twelve findings reproduced against the shipped code; two were worse than reported. The four here are the ones a user meets first. The rest — the silent-negative family, skip dialects, cross-file test moves, packaging — follow.
|
|
210
261
|
|
|
211
262
|
## [0.64.0] - 2026-09-04
|
|
212
|
-
*A guard that cannot read your dialect must say so, not pass.*
|
|
213
263
|
|
|
214
264
|
### Fixed
|
|
215
265
|
- **The Package We Published Was Not The Tree We Tested (`package.json`, `src/guard-policy.mjs`)**: `scripts/guard-reach-check.mjs` shipped in the tarball while the policy contract it imports did not, because `files` lists `scripts/` and not `test/`. Unpacked and run, it threw `ERR_MODULE_NOT_FOUND`. The check whose entire purpose is to prove that no guard has silently gone missing was itself silently missing — and every signal that should have caught it (1015 tests, a nine-way matrix, a blocking release) was measured in the source tree, where the file exists by construction. The contract now lives in `src/`, where it is part of the product it describes.
|
|
@@ -229,7 +279,6 @@ Found by a cold-start trial conducted as an unprimed stranger — install from t
|
|
|
229
279
|
- **Test-Language Coverage (`src/security.mjs`)**: `.java`, `.kt`, `.scala`, `.groovy`, `.swift`, `.cs`, `.php`, `.c`, `.cpp`, `.m`, `.sol` and `.rb` are now named explicitly rather than falling through to the JavaScript scanner by default, which is how a `#` comment came to be read as code.
|
|
230
280
|
|
|
231
281
|
## [0.63.0] - 2026-09-04
|
|
232
|
-
*A defect that turns a check off cannot be found by the check it turns off.*
|
|
233
282
|
|
|
234
283
|
### Added
|
|
235
284
|
- **Activation Coverage (`scripts/guard-reach-check.mjs`, blocking in CI and in `npm run release`)**: the question no existing mechanism could ask — *can every blocking guard still be made red?* When `isTestFile` matched the substring `/test/` and went silent for the standard pytest, Rust and RSpec layouts, five independent safety mechanisms all reported green while working exactly as designed. The unit suite sampled the same distribution the implementation was written from, so its fixtures re-confirmed the dialect it already knew. The doc-sync gate compares counts and versions, and a guard that guards nothing still contributes passing tests. The nine-way CI matrix varies OS and Node version — dimensions orthogonal to the defect; nine runs of `test/foo.test.js` never explore `tests/test_calc.py`. Cold review reads code against its stated intent, and there the code and the intent agreed: the eye supplies the leading slash. And the release gate is a conjunction over those four, where a signal that silently goes absent contributes `true`.
|
|
@@ -245,7 +294,6 @@ Found by a cold-start trial conducted as an unprimed stranger — install from t
|
|
|
245
294
|
Both independent analyses of how the classifier defect survived converged on this mechanism — canaries plus activation coverage, and the rule that a guard must report what it examined rather than only what it found. Neither had seen the other's work.
|
|
246
295
|
|
|
247
296
|
## [0.62.0] - 2026-09-04
|
|
248
|
-
*A guard that reports "pass" without saying what it examined is reporting the wrong thing.*
|
|
249
297
|
|
|
250
298
|
### Fixed
|
|
251
299
|
- **A File's Existence Was Taken As A Claim About Its Contents (`src/stack-detector.mjs`)**: a `Makefile` in the root produced `make test` whether or not it declared a `test` target — measured on a repository whose `package.json` declared a perfectly good `vitest run`, where `make test` exits 2 with "No rule to make target". A hard red on day one is how a user learns the gate is broken and turns it off. `app.json` likewise claimed a Node stack for a Rust repository with no `package.json` in it. Both now have to earn the claim.
|
|
@@ -263,7 +311,6 @@ Both independent analyses of how the classifier defect survived converged on thi
|
|
|
263
311
|
Two independent analyses of the same question — one from an external agent, one run here — converged on the same four findings about `init` without seeing each other's work, which is stronger evidence than either alone. Each finding was reproduced against the shipped code before it was changed. Two further findings arrived from a separate analysis of how the classifier defect in v0.59.0 survived five independent safety mechanisms; both named the class, and both proposed the same remedy: a guard must report what it examined, never only what it found.
|
|
264
312
|
|
|
265
313
|
## [0.61.0] - 2026-09-04
|
|
266
|
-
*A command that ran is not a command that tested something.*
|
|
267
314
|
|
|
268
315
|
### Fixed
|
|
269
316
|
- **A Runner That Collected Nothing Counted As Verification (`src/ops/test-collection.mjs`, `src/engine.mjs`)**: the gate's oracle is one number — the verification command's exit code — and that number cannot tell "every test passed" from "there were no tests". Several runners report the second as success by design: `go test ./...` prints `[no test files]` and exits 0, jest has `--passWithNoTests`, and `npm test --workspaces` is green when the one package the diff touched has no suite. So a change could invert a function, add an untested one, and collect five green phases, verified against nothing at all. The v0.57.0 `missingOracle` check catches "no stage executed"; it cannot catch "a stage executed and tested nothing". The collected count is now read out of the runner's own summary (node:test, pytest, cargo, jest, vitest, mocha, go) and a stated zero fails the verify phase as `empty-suite`.
|
|
@@ -274,7 +321,6 @@ Two independent analyses of the same question — one from an external agent, on
|
|
|
274
321
|
Identified in an independent analysis of the oracle problem, which named the collection floor and cross-revision discrimination as the two gaps that are still *checks* rather than proxies for effort. The floor is shipped here. Discrimination — running the new tests against the base revision, and failing when they pass on both — is not, and is under consideration: its own author estimates a 10–25% false-positive rate on behaviour-preserving refactors, which is above the rate at which an operator starts reaching for the override by reflex.
|
|
275
322
|
|
|
276
323
|
## [0.60.0] - 2026-09-03
|
|
277
|
-
*Making the expectation guard worth reading a month from now.*
|
|
278
324
|
|
|
279
325
|
### Fixed
|
|
280
326
|
- **One Override For Six Checks (`src/security.mjs`, `bin/agentctl.mjs`)**: `--allow-test-modifications` returned early from `checkTestTampering`, so the only way to accept a legitimately changed expectation was to also switch off injected `.skip()`, `expect(true).toBe(true)`, commented-out assertions, outright deletions and weakened assertions — none of which the operator had looked at. That makes the check with the highest firing rate the ceiling for every other check in the bundle: the more useful the expectation check became, the more often it would be used to turn the others off. `--allow-test-change <kind>` now accepts exactly one (`expectation`, `removal`, `weakening`, `skip`, `vacuous`, `commented`, or `all`), takes a list, rejects a name it does not recognise rather than guessing, and the violation message names the narrow flag instead of the blunt one. `--allow-test-modifications` still means all six.
|
|
@@ -282,7 +328,6 @@ Identified in an independent analysis of the oracle problem, which named the col
|
|
|
282
328
|
- **Rewording A Failure Message Reported A Rewritten Expectation (`src/security.mjs`)**: a message is a string literal, so blanking literals made `assert.equal(f(1), 1, "should be one")` and `assert.equal(f(1), 1, "must be one")` the same shape, and improving the wording of a failure fired a CRITICAL finding. Assertion arguments are now compared position by position, and a difference confined to a message position is not an expectation change — trailing for `assert.equal(got, want, "…")` and `assert_eq!(a, b, "…")`, leading for Go's `t.Errorf("got %d want %d", …)`. Two arguments stays the classic `(actual, expected)` shape, so `assert.equal(name(), "Alice")` → `"Bob"` still fires, as does a Go table's `want` value when only the format string was left alone.
|
|
283
329
|
|
|
284
330
|
## [0.59.0] - 2026-09-03
|
|
285
|
-
*The bypass I found in my own new check, closed by someone else — and the larger hole they noticed while closing it.*
|
|
286
331
|
|
|
287
332
|
### Fixed
|
|
288
333
|
- **Five Modules Disagreed On What A Test File Is (`src/test-paths.mjs`, and five callers)**: `security.mjs` matched the substring `/test/`, which has no match in `tests/test_calc.py` — so the standard pytest layout, the standard Rust integration layout (`tests/*.rs`) and every RSpec suite (`spec/`) were not test files, and *the entire tamper guard was switched off for them*: skip injection, vacuous assertions, commented-out assertions, removal, weakening, expectation rewrites, all silent. `mutation.mjs` had the same substring bug pointed the other way and mutated operators inside those tests, scoring the result. `engine.mjs` never looked for `_test.`, so `strictTestLock` did not consider a Go test file to be a test file. `coverage.mjs` and `evidence.mjs` each had a fourth and fifth spelling. A predicate carrying this much weight cannot have five definitions; `isTestPath` is now the only one, matching whole path segments rather than substrings (so `latest/` is not `test/`) and covering pytest's `test_*.py`, Go's `_test.go`, RSpec's `_spec.rb` and Foundry's `.t.sol`.
|
|
@@ -293,7 +338,6 @@ Identified in an independent analysis of the oracle problem, which named the col
|
|
|
293
338
|
The statement-level pairing, the per-language scanners and the numeric-literal fix arrived as [PR #14](https://github.com/FullThrottle83/jules-orchestrator-kit/pull/14) from an external coding agent, in response to the multi-line bypass being published as an open problem. Verified independently — reproduced against the shipped CLI, re-run on this machine, probed for false positives on realistic diffs — before merging. The test-path classifier is the hole that PR noticed and deliberately left alone as out of scope; it turned out to be the larger of the two.
|
|
294
339
|
|
|
295
340
|
## [0.58.0] - 2026-09-03
|
|
296
|
-
*A second cold review, from a reviewer who had never seen the project. Seven findings, all reproduced against the shipped CLI before anything was changed — and two more that only surfaced while fixing them.*
|
|
297
341
|
|
|
298
342
|
### Fixed
|
|
299
343
|
- **A Lock Taken From The CLI Locked Nothing (`src/state.mjs`, `bin/agentctl.mjs`)**: `acquireLock` stored `process.pid` and tested it for liveness on the next call — but `agentctl lock acquire` writes the record and exits *by design*, so that test always answered "dead". The next acquire reaped the lock as abandoned and granted the same files to a second agent, telling both they had exclusive access. Two agents editing one file while the mutex reported success is worse than no mutex at all. A record written by a one-shot caller now marks itself `leased` and is bounded by `expiresAt` alone; `--ttl <minutes>` sets the window and `--pid <n>` binds the lock to a real long-lived process when there is one. In-process callers (the engine, the swarm) keep pid liveness, so a crash still cannot wedge the repository.
|
|
@@ -309,7 +353,6 @@ The statement-level pairing, the per-language scanners and the numeric-literal f
|
|
|
309
353
|
- **A Signed Literal Broke Its Own Detector (`src/security.mjs`)**: the first cut of the expectation-rewrite check normalised `3` and `-1` to different shapes, because `\b` finds no boundary before a leading minus. The pair never matched and the attack it was written for still passed. The sign belongs to the literal.
|
|
310
354
|
|
|
311
355
|
## [0.57.0] - 2026-09-03
|
|
312
|
-
*The last four review findings — and two more that only surfaced once the fourth stopped lying.*
|
|
313
356
|
|
|
314
357
|
### Fixed
|
|
315
358
|
- **Generated TDD Oracles Were Always JavaScript (`src/ops/tdd-generator.mjs`)**: `test-gen` emitted a `node:test` file for every stack and then, in a Python project, ran `pytest generated-x.test.mjs`. pytest exits 4 on a file it cannot collect, and the cycle read any non-zero exit as RED — so it reported a verified failing oracle, and locked an uncollectable file into `scope.deny`, having proven nothing. Oracles are now written in the runner's language (pytest for Python/Django, a `tests/*.rs` integration test for Cargo, `*_test.go` for Go, `node:test` otherwise), and the RED check requires the generated assertion's marker in the output — a runner that never collected the file cannot pass as a falsifiable failure.
|
|
@@ -322,7 +365,6 @@ The statement-level pairing, the per-language scanners and the numeric-literal f
|
|
|
322
365
|
- **`--min-score 0` Enforced 80 (`bin/agentctl.mjs`)**: `Number(x) || 80` swallows a legitimate zero, so the documented way to run the harness for its report without a threshold quietly applied the default instead.
|
|
323
366
|
|
|
324
367
|
## [0.56.0] - 2026-09-03
|
|
325
|
-
*Three advertised features that were never wired into the execution path, plus two bugs only a live provider call could surface.*
|
|
326
368
|
|
|
327
369
|
### Fixed
|
|
328
370
|
- **Locks Did Not Lock Files (`src/state.mjs`)**: the lock file was named after the task, so `acquireLock()` only ever asked "is this same task already running?". The `files` argument — the entire point of the call — was stored as metadata and compared against nothing, so two agents could each be told they held exclusive access to the same path. Requested paths are now checked against every live lock, separators normalised first, and a conflict names the holder and the overlapping files.
|
|
@@ -335,7 +377,6 @@ The statement-level pairing, the per-language scanners and the numeric-literal f
|
|
|
335
377
|
- **Test Fixture Wrote Into The Repository (`test/ooda_thrash.test.mjs`)**: the OODA thrash fixture built its temp tree under `.agent/` of the checkout being tested, leaving debris behind whenever a run was interrupted — in a consumer's repository that debris is theirs to clean up. Moved to the OS temp directory.
|
|
336
378
|
|
|
337
379
|
## [0.55.0] - 2026-09-03
|
|
338
|
-
*Verification integrity. Three more ways an agent's work could look checked without being checked, all reproduced before being fixed.*
|
|
339
380
|
|
|
340
381
|
### Security
|
|
341
382
|
- **Test Weakening By Replacement (`src/security.mjs`)**: `checkTestTampering` counted assertions — `removed.length > added` — so swapping `assert.strictEqual(add(2,3), 5)` for `assert.ok(add(2,3) !== undefined)` was one out and one in, the guard stayed silent, and the suite stopped checking the answer. Assertions that name an expected value are now counted separately across dialects (`strictEqual`/`toBe`/`assert_eq!`/`require.Equal`/`t.Errorf`), and a fall in that count is reported as `ASSERTION_WEAKENED`. Strengthening, renaming and adding are unaffected; an assertion deleted outright stays a single `ASSERTION_REMOVAL` rather than being reported twice.
|
|
@@ -346,7 +387,6 @@ The statement-level pairing, the per-language scanners and the numeric-literal f
|
|
|
346
387
|
- **`parseRawDiff()` (`src/git.mjs`)**: the `git diff --raw -z` parsing behind binary sizing and symlink detection lives in one place rather than two.
|
|
347
388
|
|
|
348
389
|
## [0.54.1] - 2026-09-03
|
|
349
|
-
*Security hotfix. Three ways the gate could report APPROVED for work it had not checked, all found by a cold-start adversarial review and all reproduced before being fixed. The first two predate this series — the false green is present in 0.52.8.*
|
|
350
390
|
|
|
351
391
|
### Security
|
|
352
392
|
- **The Gate Approved Changes It Never Verified (`src/engine.mjs`, `src/config.mjs`)**: `testResult` started optimistic and the stage loop skipped any stage without a command, so a repository with no test oracle ran **zero** verification steps and was told `APPROVED (Exit 0)` — syntactically broken code included. The gate now fails closed (`Exit 4`, stage `oracle`) when no command executed against the change, naming `agentctl bootstrap` and `verify.test` as the fix. Assertions do not count as verification: `assert:test-integrity` proves a test was not weakened, not that the code works. A repository that deliberately uses only the scope and secret phases opts out with `verify.required: false`, read from the base commit like every other trusted field so an uncommitted edit cannot switch the gate off.
|
|
@@ -357,7 +397,6 @@ The statement-level pairing, the per-language scanners and the numeric-literal f
|
|
|
357
397
|
- **Wrong Remediation For A Missing Oracle (`bin/agentctl.mjs`)**: the exit-4 hint offered `--fix`, which cannot help when there was no command to run and no failure to repair.
|
|
358
398
|
|
|
359
399
|
## [0.54.0] - 2026-09-03
|
|
360
|
-
*First-run friction pass. Every item here was found by running a fresh dummy project through the whole chain; the engine was not the problem, the CLI's presentation layer was.*
|
|
361
400
|
|
|
362
401
|
### Fixed
|
|
363
402
|
- **Hardcoded `main` Base Branch (`src/git.mjs`, `src/wizard-init.mjs`, `bin/agentctl.mjs`)**: `init` scaffolded `base_branch: main` without ever asking git what the repository uses, so the very first `agentctl check` in any repo created on `master` (still the default of many installed gits) or standardised on `develop` failed to resolve its base ref. New `detectDefaultBranch()` resolves `origin/HEAD`, then a local `main`/`master`, then the checked-out branch (covering a repo with no commits yet), then `main`. `agentctl coverage` separately ignored `config.baseBranch` and assumed `main`; it now honours it.
|
|
@@ -958,3 +997,138 @@ The statement-level pairing, the per-language scanners and the numeric-literal f
|
|
|
958
997
|
## [0.3.0]
|
|
959
998
|
### Added
|
|
960
999
|
- Epistemic Bridge support: Cryptographic Handshake Token generation for Web UI synchronization.
|
|
1000
|
+
|
|
1001
|
+
---
|
|
1002
|
+
|
|
1003
|
+
## Archived Roadmap Milestone Summaries (v0.20.0 – v0.65.0)
|
|
1004
|
+
|
|
1005
|
+
Curated milestone summaries relocated verbatim from `ROADMAP_V1.md` during the P10 documentation
|
|
1006
|
+
consolidation, so the roadmap keeps only the last 10 shipped versions. These are archival highlights,
|
|
1007
|
+
not release entries: the per-release notes for every version above (Keep a Changelog format,
|
|
1008
|
+
`## [x.y.z] - date` headings) are the canonical history and remain untouched.
|
|
1009
|
+
|
|
1010
|
+
### v0.65.0: The First Hour
|
|
1011
|
+
- [x] **The Quickstart No Longer Rejects Its Own Output (`src/engine.mjs`)** — `init` wrote the scaffold, told the user to commit it, and the gate called that commit a scope violation while advising `--allow-protected`.
|
|
1012
|
+
- [x] **A Stated Count Outranks A Phrase (`src/ops/test-collection.mjs`)** — a healthy 190-test TAP suite was rejected as empty because a skipped fixture printed `no tests found`.
|
|
1013
|
+
- [x] **`init` Probes On The Headless Path (`src/wizard-init.mjs`)** — `--yes` means "do not ask me", not "do not check".
|
|
1014
|
+
- [x] **`verify.minTests` Reaches The Floor (`src/engine.mjs`)** — the failure message named a lever that was connected to nothing.
|
|
1015
|
+
|
|
1016
|
+
### v0.64.0: What The Guard Could Not Read
|
|
1017
|
+
- [x] **The Package Is Checked The Way It Is Installed (`scripts/package-integrity-check.mjs`)** — the tarball's own import graph, resolved inside the tarball. The previous release shipped the activation-coverage check without the contract it imports.
|
|
1018
|
+
- [x] **Five Silent Ecosystems (`src/security.mjs`)** — JUnit, RSpec, PHPUnit, Minitest and XCTest all returned `PASS` on a rewritten expected value, and `assertEqual` had been working only by accident.
|
|
1019
|
+
- [x] **`UNREADABLE` (`src/security.mjs`)** — coverage ending is fine; coverage ending silently is not.
|
|
1020
|
+
- [x] **Contracts For The Opposite Failure (`src/guard-policy.mjs`)** — ten ordinary edits that must produce no finding, because a guard that flags everything is switched off within a week.
|
|
1021
|
+
|
|
1022
|
+
### v0.63.0: Can It Still Go Red?
|
|
1023
|
+
- [x] **Activation Coverage (`scripts/guard-reach-check.mjs`)** — Blocking in CI and in the release. Eleven known-bad canaries across six ecosystems must each still produce the finding they name; four hand-written mutants of the applicability predicate must each break at least one. Runs in 88 ms.
|
|
1024
|
+
- [x] **A Hand-Written Policy Contract (`src/guard-policy.mjs`)** — Derived from what the tool advertises, never from the regexes that implement it, so the implementation cannot be its own oracle.
|
|
1025
|
+
- [x] **Verdicts Carry Their Denominator (`src/security.mjs`)** — `checkTestTampering` reports `inputsSeen` and a `PASS`/`FAIL`/`NOT_APPLICABLE` status, so "checked and clean" is no longer byte-identical to "nothing was checked".
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
### v0.62.0: No Denominator, No Claim
|
|
1029
|
+
- [x] **A File Is Not A Claim (`src/stack-detector.mjs`)** — `make test` requires the Makefile to declare the target; `app.json` requires a package.json beside it; a `test` script that is `echo … && exit 0` is a placeholder, not an oracle.
|
|
1030
|
+
- [x] **The Generated Fallback Oracle Can Fail (`src/stack-detector.mjs`)** — It checks that every source file parses instead of asserting that the working directory exists, and refuses to pass with nothing to check.
|
|
1031
|
+
- [x] **Lockfiles And Toolchain Pins Are Protected (`src/config.mjs`)** — `package.json` was protected and `package-lock.json` was not. Plus `.envrc`, `.git-credentials`, cloud credential trees and CodeBuild.
|
|
1032
|
+
- [x] **The Sixth Spelling Of "Where Are The Tests" (`src/evidence.mjs`)** — Go co-located tests and every monorepo produced `fileCount: 0`, which switched `strictTestLock` off in silence.
|
|
1033
|
+
- [x] **Seven More Runners In The Collection Floor** — Maven, Gradle, PHPUnit, RSpec, dotnet, XCTest, ctest, ExUnit.
|
|
1034
|
+
- [x] **100% Of Nothing Is Not 100% (`src/coverage.mjs`)** — Diff coverage reports `scored: false` where V8 measured nothing, instead of the best possible number.
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
### v0.61.0: Green Against Nothing
|
|
1038
|
+
- [x] **Collection Floor (`src/ops/test-collection.mjs`)** — A verification command that exits 0 having collected zero tests is no longer a pass. The count is read from the runner's own summary across node:test, pytest, cargo, jest, vitest, mocha and go; an unrecognised runner states no count and is not failed for it.
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
### v0.60.0: A Guard Worth Reading
|
|
1042
|
+
- [x] **Per-Check Overrides (`--allow-test-change <kind>`)** — Answering one tamper finding no longer silences the five other checks in the bundle. `--allow-test-modifications` remains as the blunt form.
|
|
1043
|
+
- [x] **Unchanged Assertions Cancel Before Pairing (`src/security.mjs`)** — Reordering or moving an assertion is no longer reported as two rewritten expectations.
|
|
1044
|
+
- [x] **A Reworded Message Is Not A Rewritten Expectation (`src/security.mjs`)** — Message-position string arguments are compared apart from value positions, so improving the wording of a failure is silent while `assert.equal(name(), "Alice")` → `"Bob"` still fires.
|
|
1045
|
+
|
|
1046
|
+
|
|
1047
|
+
### v0.59.0: One Answer Per Question
|
|
1048
|
+
- [x] **One Test-Path Classifier (`src/test-paths.mjs`)** — Five modules had five definitions of "is this a test file?"; the tamper guard's could not see `tests/test_calc.py`, so every check in it was off for the standard pytest, Rust and RSpec layouts. All five now share `isTestPath`.
|
|
1049
|
+
- [x] **Statement-Level Expectation Pairing (`src/security.mjs`)** — Assertions are reassembled from the diff's two images before pairing, so wrapping one across lines no longer walks through the guard. Contributed as PR #14 by an external agent; verified and merged.
|
|
1050
|
+
- [x] **Numeric Literals Beyond Decimal (`src/security.mjs`)** — Hex, binary, octal, exponent and underscored literals normalise, so `0xFF` → `0xFE` is a rewritten expectation like any other.
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
### v0.58.0: Locks That Lock
|
|
1054
|
+
- [x] **A CLI Lock Is A Lease (`src/state.mjs`, `bin/agentctl.mjs`)** — `lock acquire` no longer witnesses its own exiting process, so two agents can no longer both hold the same file. `--ttl` bounds it; `--pid` binds it to a real long-lived process instead.
|
|
1055
|
+
- [x] **A URL No Longer Disables The Secret Scanner (`src/security.mjs`)** — URLs, data: URIs and integrity hashes are stripped from a line rather than skipping the whole line, and a URL's userinfo and query values are scanned on their own.
|
|
1056
|
+
- [x] **Untracked Symlinks Are Judged By Their Target (`src/git.mjs`)** — Working-tree mode resolves links git has never seen, and a symlink is rendered as its target *path* rather than read through.
|
|
1057
|
+
- [x] **Rewritten Expectations Are Reported (`src/security.mjs`)** — An assertion whose literal changed while its shape did not is `ASSERTION_EXPECTATION_CHANGED`, with `--allow-test-modifications` as the documented override.
|
|
1058
|
+
- [x] **Scope Guard Covers Every Forge (`src/config.mjs`)** — GitLab, CircleCI, Jenkins, Azure, Travis, Drone, Buildkite and Woodpecker definitions are denied alongside `.github/**`; build and test-runner configuration is protected.
|
|
1059
|
+
- [x] **Python Runs As A Module (`src/stack-detector.mjs`)** — `python -m pytest` under whichever interpreter name this machine has, so an ordinary layout is not rejected on first contact.
|
|
1060
|
+
- [x] **Build Artifacts Do Not Read As Tampering (`src/evidence.mjs`)** — Caches a test run writes itself are excluded from the integrity hash.
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
### v0.57.0: Honest Reporting
|
|
1064
|
+
- [x] **Stack-Native TDD Oracles (`src/ops/tdd-generator.mjs`)** — Generated in the runner's own language, with a RED check that requires the assertion to have actually run rather than accepting any non-zero exit.
|
|
1065
|
+
- [x] **JSON Envelopes Reach The DAG Runner (`src/dag-engine.mjs`)** — `isDagTaskFile` is exported and used for the CLI's count, so a queue of `.json` envelopes is no longer reported as empty.
|
|
1066
|
+
- [x] **`swarm` Honours Its Flags (`bin/agentctl.mjs`)** — `--json`, `--dry-run` and `--concurrency` are parsed, and the registry describes a dispatcher rather than an inspector.
|
|
1067
|
+
- [x] **No Score Where Nothing Was Measured (`src/mutation.mjs`)** — An empty mutant population reports `null` and a reason instead of a vacuous 100%.
|
|
1068
|
+
- [x] **New Files Are Visible To Every Gate (`src/git.mjs`)** — The synthetic diff for an untracked file carries a `@@` header, so mutation and diff coverage can place its lines at all.
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
### v0.56.0: Wired, Not Just Shipped
|
|
1072
|
+
- [x] **File-Aware Locking (`src/state.mjs`)** — `acquireLock()` compares the requested paths against every live lock instead of only the task id.
|
|
1073
|
+
- [x] **Checkpoints That Exist (`src/engine.mjs`, `src/session-ops.mjs`)** — Taken before a dispatch and before `patch --apply`, so `agentctl rollback` finally has something to restore.
|
|
1074
|
+
- [x] **Reachable Monorepo Scoping (`verify.scope: affected`)** — The boundary resolver is called by the gate, opt-in, defaulted on for repositories detected as monorepos and widening again when a shared file changes.
|
|
1075
|
+
- [x] **Process-Group Reaping For The Test Runner (`scripts/run-tests.mjs`)** — An interrupted run takes its whole tree with it instead of orphaning every process below the first level. A first instance of the v0.60.0 guillotine, applied where the leak was actually observed.
|
|
1076
|
+
- [x] **Live-Path Corrections (`src/provider.mjs`, `src/engine.mjs`)** — `listSources()` works against the real API, and Node's test-runner context no longer masks a failing verification command.
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
### v0.55.0: Verification Integrity
|
|
1080
|
+
- [x] **Assertion Weakening Detection (`src/security.mjs`)** — A specific expectation swapped for a vague one is reported as `ASSERTION_WEAKENED`, closing the one-out-one-in bypass that counting assertions could never see.
|
|
1081
|
+
- [x] **Symlink-Aware Scope (`src/git.mjs`, `src/engine.mjs`)** — Added links are judged by the path they resolve to as well as their own name, without following anything on disk.
|
|
1082
|
+
- [x] **Source-Bound Evidence (`src/evidence.mjs`)** — Manifests attest to the source tree, not only the tests, and the integrity hash finally sees test files that live at the repository root.
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
### v0.54.1: The Gate Fails Closed
|
|
1086
|
+
- [x] **No Oracle, No Approval (`src/engine.mjs`)** — A change that ran zero verification commands is rejected rather than approved; `verify.required: false` is the deliberate opt-out, read from the base commit.
|
|
1087
|
+
- [x] **Binary Payload Inspection (`src/security.mjs`, `src/git.mjs`)** — Files git renders as "Binary files ... differ" are read directly for structured credentials, closing the NUL-byte bypass, and their real size is charged against the payload ceiling.
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
### v0.54.0: First-Run Friction — Honest Errors, Detected Defaults
|
|
1091
|
+
- [x] **Base Branch Detection (`src/git.mjs`)** — `detectDefaultBranch()` resolves `origin/HEAD`, a local `main`/`master`, then the checked-out branch, replacing the hardcoded `main` that failed the first gate in every `master` or `develop` repository.
|
|
1092
|
+
- [x] **Diagnosable Gate Output (`bin/agentctl.mjs`, `src/ops/verify-output.mjs`)** — Phase errors are rendered instead of swallowed, and a failing stage's stdout is no longer discarded because the spawn wrapper wrote one line to stderr.
|
|
1093
|
+
- [x] **Truthful Remediation Hints (`bin/agentctl.mjs`)** — Test tampering no longer advises rotating API keys, and a provider that refused the dispatch is no longer reported as an exhausted repair loop.
|
|
1094
|
+
- [x] **Provider-First Onboarding & `agentctl provider set` (`src/wizard-init.mjs`, `src/config-edit.mjs`)** — The wizard asks which agent before asking about one vendor's plans, and switching providers no longer means re-running onboarding.
|
|
1095
|
+
- [x] **Named Targets And Flags Actually Take Effect (`bin/agentctl.mjs`, `src/ops/ide-scaffold.mjs`, `src/ops/cli-intent.mjs`)** — `mcp init <target>`, `task create --title/--prompt` and `doctor --probe` all did something other than what they said; each now does what it says, or is no longer advertised.
|
|
1096
|
+
- [x] **Onboarding Trap Distinguished From Overreach (`src/git.mjs`)** — `partitionTracked()` tells uncommitted scaffolding apart from an agent editing its own rules, so the first-run exit 3 advises committing rather than bypassing the gate.
|
|
1097
|
+
- [x] **Rehearsals Write Nothing (`src/wizard-task.mjs`)** — `task create --dry-run` synthesizes and validates the envelope without queueing it.
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
### v0.53.0: Universal Portability — Any Stack, Any Agent, Any CI
|
|
1101
|
+
- [x] **Provider Readiness Probe (`src/provider-readiness.mjs`, `agentctl providers`)** — Per-provider capability descriptors: a credential for the hosted `jules` adapter, a `PATH` binary for the `claude-code`/`codex`/`gemini-flash` exec adapters, with a cross-platform PATHEXT-aware resolver that spawns nothing.
|
|
1102
|
+
- [x] **Vendor-Neutral Environment Spellings (`src/env-aliases.mjs`)** — Every `JULES_*` knob also answers to `AGENT_*`, normalised once at CLI entry, with the legacy name always winning.
|
|
1103
|
+
- [x] **Verification Profiles (`src/profiles.mjs`, `agentctl profile`)** — `minimal | standard | max` expanded at load time into a stack-aware pipeline that skips unsupported gates with a stated reason rather than failing the diff.
|
|
1104
|
+
- [x] **Generated Stack-Aware CI (`src/ci-templates.mjs`, `agentctl ci init`)** — GitHub Actions and GitLab jobs carrying the detected stack's toolchain, replacing the copy of this repository's own nine-way Node matrix.
|
|
1105
|
+
- [x] **Consumer Repository Hygiene (`bin/init.js`)** — `init` no longer copies the kit's twenty internal scripts into the target repository, and both entry points now write the same manifest pair.
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
### v0.52.x: Entropy Hardening, Egress Auditing & CI Defense
|
|
1109
|
+
- [x] **Binary Asset Classification Guard (`src/security.mjs`)** — Restricts binary asset skipping to tokens $\ge 256$ chars, preventing length $\pmod 4 = 0$ keys from bypassing entropy checks.
|
|
1110
|
+
- [x] **CI Runtime & Egress Security (`.github/workflows/*.yml`)** — Linux eBPF runtime monitoring and network egress auditing via StepSecurity.
|
|
1111
|
+
- [x] **GitHub Actions Supply Chain Hardening (`.github/`)** — Action SHA pinning, least-privilege `contents: read`, and automated Zizmor CI gate.
|
|
1112
|
+
- [x] **Assertion Removal & Anti-Tamper Guard (`src/security.mjs`)** — Detects test deletion bypass (`ASSERTION_REMOVAL`) and vacuous assertion weakening.
|
|
1113
|
+
- [x] **Shannon Entropy Diff Scanner (`src/security.mjs`)** — High-entropy token detection (>4.5 entropy, $\ge 24$ chars) on added diff lines.
|
|
1114
|
+
- [x] **Jules API Patch Ingestion & Edge Webhooks (`src/session-ops.mjs`, `src/webhook.mjs`)** — API changeset extraction and Webhook `Uint8Array` Edge runtime parity.
|
|
1115
|
+
- [x] **Zero-Test Oracle Bootstrapping & Git Remote Origin Auto-Detection (`src/stack-detector.mjs`, `src/git.mjs`)** — Auto-configuration for virgin repositories.
|
|
1116
|
+
|
|
1117
|
+
### v0.51.0: Mechanical Falsification, AST Mutation & V8 Coverage
|
|
1118
|
+
- [x] **Diff-Hunk Mutation Testing Engine (`src/mutation.mjs`, `agentctl mutate`)** — Transactional operator inversion with automatic shadow disk rollback.
|
|
1119
|
+
- [x] **Native V8 Diff Coverage Enforcer (`src/coverage.mjs`, `agentctl coverage`)** — Zero-dependency V8 coverage mapping against added `+` hunks.
|
|
1120
|
+
- [x] **Test-Oscillation Cycle Detector (`src/remediation.mjs`, `src/engine.mjs`)** — Halts multi-test oscillation cycles in OODA repair loops.
|
|
1121
|
+
- [x] **Flakiness Stability Prober & Event Loop Delay Guard (`src/stability.mjs`, `src/perf.mjs`)** — Multi-pass repetition probing and Big-O event loop delay monitor.
|
|
1122
|
+
|
|
1123
|
+
### v0.40.0 – v0.50.0: Architecture Governance & Universal Envelopes
|
|
1124
|
+
- [x] **Universal Stack-Agnostic Task Templates (`src/web-templates.mjs`)** — Pre-calibrated templates for Cargo, Go, Python, PHP, .NET, Java, and Node.
|
|
1125
|
+
- [x] **Specialist Agent Roles (`.agent/prompts/`)** — Eight stack-neutral specialist personas with dynamic command hydration.
|
|
1126
|
+
- [x] **All-In-One CI Verification Gate (`agentctl check`)** — Unified security, scope, payload, and stack test gatekeeper.
|
|
1127
|
+
- [x] **Stack-Tailored Contract Scaffolding (`src/scaffold.mjs`)** — Automatic `SPEC.md`, `CONSTRAINTS.md`, and `DESIGN.md` generation on init.
|
|
1128
|
+
|
|
1129
|
+
### v0.30.0 – v0.39.0: Budget Provenance, Terminal UX & Autonomous Resilience
|
|
1130
|
+
- [x] **Rolling 24h Budget Ledger & Limit Provenance (`src/budget.mjs`, `agentctl budget`)** — Multi-user attribution, rolling window accounting, and graceful estimate warnings.
|
|
1131
|
+
- [x] **Terminal UI Engine (`src/tui.mjs`, `src/key-decoder.mjs`)** — Zero-dependency interactive selection, multi-select, secret masking, and raw keyboard decoding.
|
|
1132
|
+
- [x] **Multi-OS CI Matrix Parity** — 100% green suite across Linux, macOS Darwin, and Windows CMD/PowerShell on Node 20, 22, and 24.
|
|
1133
|
+
- [x] **Atomic Git Checkpoint & Rollback (`src/ops/checkpoint.mjs`, `agentctl rollback`)** — Pre-flight working tree snapshots and 1-command git restore.
|
|
1134
|
+
- [x] **Documentation Sync Gate (`scripts/doc-sync-check.mjs`, `npm run jules:doc-sync`)** — Mechanical enforcement preventing documentation drift across manifests, roadmaps, and tests.
|