feat(tls): add corporate CA bundles for package HTTPS - #2741
Josh Bazar (TameTheGame) wants to merge 8 commits into
Conversation
# Conflicts: # CHANGELOG.md
|
@microsoft-github-policy-service agree |
There was a problem hiding this comment.
Pull request overview
Adds opt-in additive enterprise CA support via APM_EXTRA_CA_BUNDLE, ensuring APM can trust corporate/private roots in addition to its normal trust (OS truststore when available, otherwise certifi), and propagates stable, validated CA snapshots to child processes (Python Requests children and Node children) without TOCTOU on operator-controlled files.
Changes:
- Introduces
APM_EXTRA_CA_BUNDLEwith bounded, certificate-only PEM validation; transactional publication of OS-plus-extra TLS context and robust fallback behavior. - Implements per-process CA snapshotting under
~/.apm/tls/and derives child env mappings (REQUESTS_CA_BUNDLEmerged snapshot;NODE_EXTRA_CA_CERTSextra-only snapshot) with ownership markers for nested runs. - Updates CLI early-failure handling, runtime/script spawn seams, tests, and docs/changelog to reflect the new precedence and scope boundaries.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/apm_cli/core/tls_trust.py |
Core owner for additive CA validation, transactional truststore publication, stable snapshots, child env derivation, and managed-venv bootstrap refresh. |
src/apm_cli/core/_child_tls/_apm_tls_bootstrap.py |
Managed Python bootstrap updated to support OS-plus-extra injection silently and transactionally in child interpreters. |
src/apm_cli/cli.py |
Converts early TLS configuration errors into a single Click failure before command callbacks execute. |
src/apm_cli/core/script_runner.py |
Ensures apm run spawn paths apply build_child_tls_env for both shell and runtime-exec boundaries. |
src/apm_cli/core/script_executors.py |
Ensures hardened Sessions (trust_env=False) still honor explicit CA replacement variables via the canonical helper. |
src/apm_cli/runtime/llm_runtime.py |
Ensures managed llm runtime invocations use the canonical child TLS environment (and bootstrap refresh). |
src/apm_cli/install/validation.py |
Updates TLS failure guidance to recommend additive trust (APM_EXTRA_CA_BUNDLE) before replacement (REQUESTS_CA_BUNDLE). |
CHANGELOG.md |
Adds an Unreleased entry documenting the new additive enterprise CA behavior and Node non-overwrite semantics. |
docs/src/content/docs/troubleshooting/ssl-issues.md |
Documents precedence, runtime coverage, failure behavior, and configuration recipes for additive trust. |
docs/src/content/docs/reference/environment-variables.md |
Documents APM_EXTRA_CA_BUNDLE, NODE_EXTRA_CA_CERTS, and explicit resolution order/scope. |
docs/src/content/docs/enterprise/security.md |
Updates enterprise security model with additive trust mechanics, snapshots, and precedence boundaries. |
docs/src/content/docs/enterprise/registry-proxy.md |
Updates proxy troubleshooting to prefer additive trust while retaining public roots. |
docs/src/content/docs/troubleshooting/common-errors.md |
Aligns common TLS error recovery guidance with additive trust. |
docs/src/content/docs/troubleshooting/install-failures.md |
Aligns install TLS troubleshooting with additive trust and precedence guidance. |
packages/apm-guide/.apm/skills/apm-usage/troubleshooting.md |
Keeps packaged troubleshooting guidance in sync with additive trust behavior. |
tests/unit/core/test_tls_trust.py |
Adds unit coverage for additive validation, rollback, snapshotting, ownership markers, and managed bootstrap refresh. |
tests/unit/core/test_script_runner_execution.py |
Adds unit coverage to lock TLS child env application at both runtime and shell spawn seams. |
tests/unit/test_llm_runtime.py |
Updates expectations to ensure managed runtime spawns request the llm-scoped child TLS environment. |
tests/unit/test_lifecycle_executor_paths.py |
Adds tests proving hardened Sessions honor explicit CA bundle settings even with trust_env=False. |
tests/unit/test_tls_docs_scope.py |
Updates doc drift guards to enforce runtime scope wording and additive-variable documentation. |
tests/integration/test_tls_custom_ca.py |
Adds integration coverage for additive trust behavior (parent Requests, preloaded contexts, CLI fail-fast, apm run propagation). |
tests/integration/test_tls_child_runtime.py |
Adds integration coverage for managed/foreign Python bootstraps, descendants, Node child propagation, and source mutation stability. |
tests/integration/test_tls_frozen_hook.py |
Extends frozen-hook env coverage to include additive variables and derived ownership markers. |
tests/integration/test_tls_r2_verify.py |
Extends verification coverage to include additive variables and derived ownership markers. |
tests/integration/test_tls_r3_verify.py |
Updates docs-scope integration assertions to match the new runtime-coverage wording and additive guidance. |
tests/integration/test_wave6_validation_uninstall_coverage.py |
Updates validation guidance assertions to include additive trust recommendations. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Merged upstream The merge also exposed a new architecture check: two TLS integration tests selected the CLI directly. They now consume the canonical Validation on Windows:
These are local results; upstream workflow approval and CI results remain separate. Conflict resolution and the test adaptation were performed with OpenAI Codex assistance. |
|
Resolved the new conflicts after upstream advanced again: retained the corrected 0.29.1 release date and the new MCP staging-path troubleshooting entry alongside this PR's additive TLS guidance. Merged current upstream main; no changes to this PR's TLS implementation or tests were needed. Validation for this documentation conflict resolution: all 9 TLS documentation-scope tests passed; Ruff lint/format, duplication, architecture and auth boundaries, source guards, and diff whitespace checks passed. Documentation build: 124 pages, 1,006 relative links, no broken links. The earlier 223-test runtime result remains evidence for the previous head; that broader selection was not rerun for this documentation-only resolution. Performed with OpenAI Codex assistance. Upstream workflow approval and CI results remain separate from these local checks. |
Keep rollback at the parent and child bootstrap boundaries, consolidate the parent fallback, and remove the duplicate HTTPS test server. Link the TLS reference to the existing runtime coverage explanation. Exercise fallback after actual additive-context publication. Correct the Windows CA override expectation and run the Bash probe through stdin.
|
Pushed the simplification follow-up in ec035c10. The change removes redundant inner rollback while retaining recovery around the complete parent and child operations, consolidates the parent fallback, and deletes the duplicate HTTPS test server. It also replaces repeated documentation with a link, removes temporary-file handling from the Bash probe, and corrects the Windows CA-override test expectation. The additive trust and child-runtime scope remain intact. Net change: 93 lines removed across eight files. Validation for this commit on Windows/Python 3.12.13:
The fallback regression now forces failure after actual additive-context publication and verifies that real Requests HTTPS still succeeds. Other coverage includes private-CA HTTPS, independent existing-root retention, and Python/Node child propagation. The PR description has the full validation scope. Linux/macOS execution, a fresh packaged executable, a complete private-registry Review, changes, and validation were performed with OpenAI Codex assistance. |
APM Review Panel:
|
| Persona | B | R | N | Takeaway |
|---|---|---|---|---|
| Python Architect | 0 | 0 | 1 | TLS trust is centralized in tls_trust with scoped child bootstrap and rollback; no blocking architecture issues found. |
| CLI Logging Expert | 0 | 1 | 1 | Two UX gaps remain: managed llm bootstrap refresh can fail silently, and the startup TLS hard-fail lacks a recovery hint. |
| DevX UX Expert | 0 | 0 | 0 | No DevX concerns: additive CA, precedence, child coverage, shell semantics, and unset behavior are documented and exercised. |
| Supply Chain Security | 0 | 0 | 0 | No supply-chain security regressions found in the additive CA implementation. |
| OSS Growth Hacker | 0 | 0 | 0 | Enterprise onboarding story is clear and scoped: one additive CA knob, runnable docs, and honest runtime boundaries. |
| Auth Expert | 1 | 0 | 0 | One shell-spawn path lets inline TLS opt-outs inherit APM-derived CA variables; token/auth policy remains isolated. |
| Doc Writer | 0 | 1 | 0 | Runtime and fallback disclosures match the amended issue; extend the inline-shell caveat to opt-out and replacement controls. |
| Test Coverage | 0 | 1 | 0 | TLS run/child/default-root tests pass; full private-CA apm install remains unguarded. |
| Performance Expert | 0 | 0 | 0 | No material performance defect found. Opt-in additive TLS adds bounded local I/O only; warm build_child_tls_env averaged 6.1 ms in a narrow local repro, with no new network RTTs or algorithmic growth. |
B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.
Top 3 follow-ups
- [Test Coverage] Add the full private-CA apm install plus default-root regression fixture. -- Issue Add additive corporate-CA support: APM_EXTRA_CA_BUNDLE (npm NODE_EXTRA_CA_CERTS parity) #2034 acceptance explicitly names apm install as well as apm run; current targeted tests pass, but the install path is still missing automated proof that a private-CA package source works without replacing normal roots.
- [Doc Writer + Auth Expert] Broaden the inline-shell TLS boundary documentation and add a focused nested-env regression trap. -- APM resolves child TLS env before shell execution, so inline opt-out or curl replacement assignments cannot remove already-derived Requests/Node settings. Users should be told to set those controls in the environment launching APM rather than inside an apm.yml shell command; do not add fragile cross-platform shell parsing.
- [CLI Logging Expert] Show a default-level notice when managed llm TLS bootstrap refresh fails at child launch. -- The fallback still carries certifi plus the extra CA and does not disable verification, but a failed managed bootstrap refresh is security-relevant degradation that should not be debug-only.
Architecture
classDiagram
direction LR
class CLI {
<<Entrypoint>>
+configure_process_tls_trust()
+cli(ctx, verbose)
}
class TLS_TRUST {
<<Facade>>
+configure_tls_trust(env) bool
+build_child_tls_env(base_env, runtime_name) dict
+explicit_ca_bundle_path(env) str
+ensure_child_tls_bootstrap(venv_path) bool
}
class TLSConfigurationError {
<<Exception>>
}
class ChildCASnapshotStore {
<<Factory>>
+_ensure_child_ca_snapshots(bundle_pem) tuple
}
class TLSPublicationState {
<<Memento>>
+_capture_tls_publication_state()
+_restore_tls_publication_state(state)
}
class ChildBootstrap {
<<BootstrapAdapter>>
+_bootstrap()
}
class ScriptRunner {
<<Spawner>>
+_execute_script_command(command, params) bool
+_execute_runtime_command(command, content, env) CompletedProcess
}
class RuntimeBase {
<<Streamer>>
+_stream_subprocess_output(cmd, timeout, env) tuple
}
class LLMRuntime {
<<RuntimeAdapter>>
+execute_prompt(prompt_content) str
+is_available() bool
}
class ScriptExecutors {
<<HardenedSessionFactory>>
+_build_guarded_session()
+_build_capturing_session()
}
class RequestsSession {
<<ExternalAdapter>>
}
class NodeRuntime {
<<ExternalRuntime>>
}
class PythonRequestsChild {
<<ExternalRuntime>>
}
CLI ..> TLS_TRUST : imports before command modules
TLS_TRUST ..> TLSConfigurationError : raises invalid additive config
TLS_TRUST *-- ChildCASnapshotStore : freezes extra and certifi-plus-extra
TLS_TRUST *-- TLSPublicationState : transactional publish/rollback
TLS_TRUST ..> ChildBootstrap : ships and refreshes
ScriptRunner ..> TLS_TRUST : build_child_tls_env()
RuntimeBase ..> TLS_TRUST : default child env
LLMRuntime ..> TLS_TRUST : runtime_name="llm"
ScriptExecutors ..> TLS_TRUST : explicit_ca_bundle_path()
ChildBootstrap ..> TLSPublicationState : local rollback copy
ChildBootstrap ..> PythonRequestsChild : preserves derived REQUESTS_CA_BUNDLE
TLS_TRUST ..> NodeRuntime : NODE_EXTRA_CA_CERTS snapshot
ScriptExecutors ..> RequestsSession : trust_env=False plus explicit verify
note for TLS_TRUST "Single authority:\nprecedence, validation,\nsnapshots, parent fallback,\nchild env mapping"
note for TLSPublicationState "Memento-style rollback:\nssl, urllib3, Requests preloaded context"
class CLI:::touched
class TLS_TRUST:::touched
class TLSConfigurationError:::touched
class ChildCASnapshotStore:::touched
class TLSPublicationState:::touched
class ChildBootstrap:::touched
class ScriptRunner:::touched
class LLMRuntime:::touched
class ScriptExecutors:::touched
classDef touched fill:#fff3b0,stroke:#d47600
flowchart TD
A["[I/O] src/apm_cli/cli.py import calls configure_process_tls_trust()"] --> B["src/apm_cli/core/tls_trust.py::configure_tls_trust(env)"]
B --> C{"has_explicit_ca_override(env)?"}
C -->|yes| D["Return False; REQUESTS_CA_BUNDLE or CURL_CA_BUNDLE remains replacement authority"]
C -->|no| E{"APM_DISABLE_TRUSTSTORE truthy?"}
E -->|yes| F["Return False; OS/additive propagation suppressed"]
E -->|no| G{"APM_EXTRA_CA_BUNDLE set?"}
G -->|yes| H["[I/O] _read_extra_ca_bundle(): resolve, fstat, size/ascii/private-key/parser validation"]
G -->|no| I["[I/O] import truststore; truststore.inject_into_ssl()"]
H --> I
I --> J{"truststore injection and _install_additive_ca_context() succeed?"}
J -->|yes| K["[I/O] publish ssl.SSLContext, urllib3.util.ssl_.SSLContext, requests.adapters._preloaded_ssl_context"]
J -->|no| L["_restore_tls_publication_state(): rollback loaded ssl/urllib3/Requests globals"]
L --> M{"extra CA was selected?"}
M -->|yes| N["[FS] _ensure_child_ca_snapshots(): write certifi-plus-extra fallback under ~/.apm/tls/apm_tls_*/"]
N --> O["[I/O] set REQUESTS_CA_BUNDLE and APM_REQUESTS_CA_BUNDLE_IS_DERIVED_ADDITIVE in os.environ"]
M -->|no| P["Return False; bundled certifi fallback only"]
K --> Q["apm command callbacks can perform HTTPS with OS-plus-extra or OS trust"]
O --> Q
Q --> R["src/apm_cli/core/script_runner.py::_execute_script_command() or _execute_runtime_command()"]
R --> S["src/apm_cli/core/tls_trust.py::build_child_tls_env(env, runtime_name)"]
S --> T["Clear APM-derived REQUESTS_CA_BUNDLE and NODE_EXTRA_CA_CERTS markers before recomputing"]
T --> U{"disable or genuine Requests/curl replacement present?"}
U -->|yes| V["[EXEC] subprocess.run(..., env=child) preserves operator-owned replacement and suppresses derived Node mapping"]
U -->|no| W["[FS] validate APM_EXTRA_CA_BUNDLE again; write/reuse extra-only and certifi-plus-extra snapshots"]
W --> X["[EXEC] Python child receives REQUESTS_CA_BUNDLE=certifi-plus-extra snapshot"]
W --> Y["[EXEC] Node child receives NODE_EXTRA_CA_CERTS=extra-only snapshot unless native value is non-empty"]
W --> Z{"runtime_name == 'llm'?"}
Z -->|yes| AA["[FS] _refresh_managed_llm_tls_bootstrap(): ensure_child_tls_bootstrap(~/.apm/runtimes/llm-venv)"]
Z -->|no| AB["No managed bootstrap refresh"]
sequenceDiagram
participant User
participant CLI as src/apm_cli/cli.py
participant TLS as src/apm_cli/core/tls_trust.py
participant Runner as src/apm_cli/core/script_runner.py
participant Child as Python/Node child process
User->>CLI: APM_EXTRA_CA_BUNDLE=/corp.pem apm run tls-probe
CLI->>TLS: configure_process_tls_trust()
TLS->>TLS: _read_extra_ca_bundle() and configure_tls_trust()
alt truststore publication succeeds
TLS-->>CLI: OS trust plus additive CA published
else publication fails after validation
TLS->>TLS: _restore_tls_publication_state()
TLS->>TLS: _ensure_child_ca_snapshots()
TLS-->>CLI: Requests fallback env uses certifi-plus-extra snapshot
end
CLI->>Runner: run command callback
Runner->>TLS: build_child_tls_env(env, runtime_name)
TLS->>TLS: clear derived markers, revalidate source, create stable snapshots
TLS-->>Runner: child env with REQUESTS_CA_BUNDLE and/or NODE_EXTRA_CA_CERTS
Runner->>Child: subprocess.run(..., env=child_env)
Child-->>Runner: HTTPS uses frozen additive trust bytes
Recommendation
Ship the additive CA feature with the three follow-ups above tracked. Treat the code and docs as aligned with the amended issue plan, but do not close the loop on #2034 as fully demonstrated until the private-CA apm install fixture is added or explicitly deferred by the maintainer; describe current workflow status as action_required, not green.
Full per-persona findings
Python Architect
- [nit] Architecture pattern note: current TLS owner shape is sufficient. at
src/apm_cli/core/tls_trust.py:452
Design patterns; Used in this PR: Facade / single-authority module -- src/apm_cli/core/tls_trust.py owns trust precedence, additive validation, child snapshots, parent fallback, and child env mapping through configure_tls_trust() and build_child_tls_env().; Used in this PR: Memento-style transactional rollback -- _capture_tls_publication_state() and _restore_tls_publication_state() keep process-wide ssl, urllib3, and Requests publication reversible when additive context installation fails.; Used in this PR: Factory -- _ensure_child_ca_snapshots() creates content-addressed extra-only and certifi-plus-extra artifacts for children rather than letting each spawn path write its own TLS files.; Pragmatic suggestion: none -- splitting this into a registry or strategy hierarchy would add indirection without a third independent TLS policy consumer; keep extending tls_trust as the canonical owner.
Suggested: Keep future TLS precedence, snapshot, and rollback changes routed through tls_trust; the existing architecture boundary guard already confines truststore.inject_into_ssl() to tls_trust and the child bootstrap.
CLI Logging Expert
- [recommended] Warn when a managed llm launch cannot refresh its TLS bootstrap. at
src/apm_cli/core/tls_trust.py:679
src/apm_cli/core/tls_trust.py degrades launch-time refresh failure to a debug-only line even though the PR and docs promise that APM refreshes the managed llm bootstrap before managed launches. In a reproduced failure where ensure_child_tls_bootstrap returned False, build_child_tls_env({}, runtime_name='llm') emitted no default-level warning and proceeded. That turns a trust-store regression into a later child TLS failure with no immediate guidance, which is the wrong default for a security-relevant runtime degradation.
Suggested: Mirror runtime_manager._install_llm_tls_bootstrap's yellow warning here, or route both paths through one shared formatter, so a failed launch-time refresh tells the user to re-runapm runtime setup llm, use Python 3.10+, or setPIP_CERTbefore the child command continues.
Proof (manual only):(no test ref)-- proves: A managed llm launch can lose the advertised bootstrap refresh with no default-level operator guidance. [secure-by-default,devx] - [nit] Add a one-line recovery hint to the early Click TLS configuration error. at
src/apm_cli/cli.py:163
src/apm_cli/cli.py raises ClickException(str(_TLS_BOOTSTRAP_ERROR)) before any command callback runs. For a mis-set APM_EXTRA_CA_BUNDLE, the surfaced text is only the raw diagnosis, for example 'APM_EXTRA_CA_BUNDLE path does not exist: ...'. That explains what is wrong but not what to do next, which is a poor first-run experience for a startup-blocking error.
Suggested: Append one short fix hint such as 'Unset APM_EXTRA_CA_BUNDLE or point it at a readable certificate-only PEM; see SSL / TLS issues.'
DevX UX Expert
No findings.
Supply Chain Security
No findings.
OSS Growth Hacker
No findings.
Auth Expert
- [blocking] Inline shell TLS opt-outs do not clear APM-derived child trust variables. at
src/apm_cli/core/script_runner.py:196
When APM_EXTRA_CA_BUNDLE is set in the environment that launches APM, the shell=True apm run path builds REQUESTS_CA_BUNDLE and NODE_EXTRA_CA_CERTS before the shell applies inline assignments such as APM_DISABLE_TRUSTSTORE=1 or REQUESTS_CA_BUNDLE=/replacement.pem. The direct child can therefore still inherit APM-derived CA trust even though the command explicitly opted out or selected replacement trust, violating the documented replacement/disable precedence and the exact-path ownership invariant for derived values.
Suggested: Add a regression test with parent APM_EXTRA_CA_BUNDLE plus an inline shell APM_DISABLE_TRUSTSTORE/REQUESTS_CA_BUNDLE assignment, then either clear derived CA variables for that shell command before exec or document and enforce that shell-inline trust policy is unsupported by failing closed instead of silently keeping the derived bundle.
Proof (manual only):(no test ref)-- proves: A direct apm run shell child can receive additive CA trust after the command-level disable is applied. [secure-by-default,governed-by-policy,multi-harness-support]
Doc Writer
- [recommended] Explain that inline opt-out and curl replacement cannot undo precomputed child trust at
docs/src/content/docs/troubleshooting/ssl-issues.md:106
The caveat explains only that an inline additive assignment is not translated for Node. With APM_EXTRA_CA_BUNDLE exported before apm run, script_runner.py:192-196 derives the environment before the shell evaluates assignments; tls_trust.py:729-739 has already populated REQUESTS_CA_BUNDLE and NODE_EXTRA_CA_CERTS. Consequently, an apm.yml shell command such as 'APM_DISABLE_TRUSTSTORE=1 node probe.js' still inherits the derived Node CA, and 'CURL_CA_BUNDLE=/replacement.pem python probe.py' leaves an ordinary Requests child using the higher-priority derived REQUESTS_CA_BUNDLE. The documented precedence can therefore mislead users attempting per-script opt-out or replacement. A search of the docs and packaged guidance found no explanation of these cases. This is missing operational guidance for the deliberately retained shell boundary, not a request to parse shell commands or a demonstrated verification bypass.
Suggested: Replace the existing inline-assignment sentence with a concise explanation that APM resolves precedence before shell execution. Tell users to set opt-out/replacement controls in the environment launching APM, for example 'APM_DISABLE_TRUSTSTORE=1 apm run probe' on POSIX, rather than inside the apm.yml shell command. Explicitly note that inline assignments do not remove already-derived Requests/Node settings.
Test Coverage
- [recommended] Add a full-install private-CA regression trap. at
src/apm_cli/cli.py:24
Issue Add additive corporate-CA support: APM_EXTRA_CA_BUNDLE (npm NODE_EXTRA_CA_CERTS parity) #2034 acceptance names both apm install and apm run, but the Scenario Evidence table maps only parent Requests plus apm run/child-runtime probes. I searched tests/integration and tests for install plus APM_EXTRA_CA_BUNDLE/private_ca_https_server/private CA overlap; the only install hits are docs/guidance or unrelated local install scenarios, and there is no apm_binary_path/CliRunner install test that drives APM_EXTRA_CA_BUNDLE through a private-CA HTTPS install fixture while also proving the default roots remain usable. The affected suite I ran passed once APM_BINARY_PATH was pinned to the snapshot-importing venv script, so this is a missing evidence gap, not a demonstrated branch regression.
Suggested: Add tests/integration/test_tls_install_custom_ca.py::test_apm_install_trusts_private_ca_and_retains_default_root using synthetic loopback roots, APM_BINARY_PATH=/.venv/bin/apm, PYTHONPATH=src, and no live Internet.
Proof (test MISSING at):tests/integration/test_tls_install_custom_ca.py::test_apm_install_trusts_private_ca_and_retains_default_root-- proves: apm install can consume a private-CA HTTPS package source via APM_EXTRA_CA_BUNDLE without replacing the normal/default trust roots. [secure-by-default,devx]
assert install.returncode == 0 and private_package_installed and default_root_probe.returncode == 0
Performance Expert
No findings.
This panel is advisory. It does not block merge. Re-apply the panel-review label after addressing feedback to re-run.
Daniel Meppiel (danielmeppiel)
left a comment
There was a problem hiding this comment.
Tahnk you for this! Please fix CodeQL vulnerabilities and the panel identified blockers + recommendations/followups
…bundle # Conflicts: # CHANGELOG.md
|
Thanks, Daniel Meppiel (@danielmeppiel). Pushed e9e0301a to address the CodeQL findings and the panel's follow-ups:
Validation on Windows/Python 3.12.13: 373 passed, 2 warnings in 83.30 seconds, with no skips or deselections. All three symlink tests passed with elevation; the two warnings are from the unchanged lifecycle timeout test's reader threads. Required Ruff/format, duplication, architecture/auth, CI source guards, and whitespace checks passed. Documentation built 124 pages and checked 1,031 relative links without errors. The branch includes upstream Would you mind approving the new workflows, reapply |
There was a problem hiding this comment.
🟡 Changes recommended
The new CHANGELOG entry does not end with a required PR reference (#PR_NUMBER) per repo changelog rules.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 29/29 changed files
- Comments generated: 1
- Review effort level: Lite
* feat: add ORIGIN x INTENT autopilot for triage, delivery, and review Replay the actor-aware autopilot surface onto origin/main as one commit: unattended runs never assign; actor-session delivery assigns the working user; standalone review requests that user as reviewer. Schedulers own the queue scripts and fan-out; workers advise or implement one item. Keep CODEOWNERS additive and require full conversation context before new advice. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): align tags and delivery with human-scope governance Keep triage/requested as the only request trigger. status/needs-triage stays human state. Delivery still queues on status/accepted, then probes scripts/governance/eligibility.cjs and requires fresh confirmation. Unattended ORIGIN never implements. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): turn monolith orchestrators into sequencing aliases apm-issue-autopilot and batch-bug-shepherd no longer implement. They dispatch the canonical schedulers in-session, with a hard stop so triage advice is not implementation permission. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): treat FANOUT_LIMIT as concurrency, not batch size Schedulers must persist and drain the full helper-selected list, refilling a slot when it returns. Two slots is parallelism only. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): stop spam-skipping bug forms; workers own writes Sweep markup strip no longer lets a heading eat the rest of the body, so valid GitHub bug forms stay eligible. Issue and PR triage workers own comments and processing labels; schedulers only queue and fan out. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): add worker activation card with optional writes Issue-triage worker declares activation_card: on. Writes default on; write: off returns the template without commenting or labeling. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): move PR-review writes off the scheduler PR-review scheduler only queues and fans out. Reviewing sessions own comments, labels, and the actor-session @me reviewer request. The composed worker gets an activation card with write default on. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): gate PR review on panel-review Unfiltered open-PR listing queued every pull request. Fresh review now requires the panel-review label or an explicit named list. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): require status/accepted before PR review panel-review only requests a pass. Without status/accepted on the PR or a linked issue, the reviewing session comments, clears the request label, and stops. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): rename review panel; silent unaccepted stop Rename apm-review-panel to autopilot-pr-review-panel and keep the old name as a compatibility alias. Scheduler, worker, and panel all stop when status/accepted is missing. Scheduler and worker leave no comment; panel/worker may clear panel-review. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): review-worker is advisory; merge-worker is drive-to-merge Keep autopilot-pr-review-scheduler advisory-only. It composes autopilot-pr-review-worker and never spawn autopilot-pr-merge-worker. Summon merge-worker by name. Old panel names stay aliases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): require Autogenesis activation cards on canonical skills Enter before work, Exit after. Do not load Autogenesis path modules. Schedulers are write off; workers default write on. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): drop Autogenesis wording from activation cards Keep Enter/Exit cards. Do not name the source discipline. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): declare activation_card on for every autopilot skill Aliases and canonical skills both set the flag. Canonical skills still own the Enter/Exit card body. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: add maintainer map for autopilot skills Internal package map only. Not product documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): nest skill packages under packages/autopilot Keep leaf package names. Move the maintainer map to packages/autopilot/README.md. Point pr-description-skill deps up one more directory. Leave .agents/skills/ deploy layout flat. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): require scheduler queue tables with labels Schedulers must emit keep-set and drop-set rows (number, kind, labels, rationale, slot) before any spawn. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): invocation is harness, not origin Copilot App, local, Cloud, and Remote Agent fill actor-session. agentic-workflow is only gh-aw / Actions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): exclude completed-advice from triage sweeps Sweep fetch skips triage/recommended and status/triaged at GitHub so already-advised open issues and PRs are not re-listed. Do not write status/triaged. Named requests still fetch the one item. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): name worker sessions Domain stage #n Issue triage #2993, PR triage #1017, Issue delivery #2902, PR review #2741. No GitHub title. Do not rename in-flight sessions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Keep issue-triage JSON internal, not on GitHub comments. The public advisory is prose plus the HTML receipt. Workers still fill schema_version 2 JSON for the parent Exit, not the issue thread. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Make triage JSON receipts optional, default off. Enter/Exit cards take json: off|on. Omitted or unknown is off, not a missing-field stop. json: on stays an internal payload; GitHub comments stay prose. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Stop the Triage Panel AW from requiring a JSON comment tail. Pass json: off into autopilot-issue-triage-worker. GitHub comments stay prose plus the HTML receipt. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Route the PR Review Panel AW through the review scheduler. Load autopilot-pr-review-scheduler (write off) then run autopilot-pr-review-worker in-thread. Do not compose the merge worker. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Auto-defer PRs with no accepted issue and thank the author. PR triage writes status/deferred unless a same-repo linked issue is status/accepted, and asks the author to open an issue first. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Queue accepted PRs for advisory review without a named list. Unsteered PR review now unions panel-review with status/accepted on the PR, then still applies the accepted gate and CODEOWNERS last-comment conditions. Named list is not required when a maintainer already accepted the PR. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Deliver accepted issues even when the author is a bot. status/accepted from a CODEOWNER is the queue gate. Author type is not a drop reason. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Remove autopilot compatibility alias stubs. Keep the nine canonical autopilot-{domain}-{stage}-{role} packages. Drop the 22 installable aliases, retarget tests to merge-worker and delivery, and refresh the lockfile. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: retarget leftover alias names to canonical autopilot skills PRINCIPLES.md, delivery/merge worker assets, and the cut-release eval note now name autopilot-{domain}-{stage}-{role} only. Historical CHANGELOG entries stay as written. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * style: ruff-format autopilot unit tests after main merge Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: refresh lock deployment hashes after alias-name retarget Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): align review sweep, auto-defer, and lock orphans Copilot App queue-open now unions panel-review with status/accepted on the PR. PR triage auto-defers only when neither the PR nor a linked issue is accepted. Drop deleted alias packages from the lockfile and retarget merge-worker eval fixtures. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(lock): rewrite deployed test-coverage-expert instruction link Install replay retargets the relative markdown link from .github/agents to .apm/instructions. The committed copy still used the source-relative path, which failed APM Self-Check drift. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): sole-assignee claim and trusted gh lookup Actor-session delivery continues only when @me is the sole human assignee after add, and re-checks before implement or PR. Triage queue helpers resolve gh through get_gh_executable so a project-controlled binary is never used. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Thank you for contributing this pull request and for the follow-up #2034 already describes the user problem, but it currently lacks This recommendation is not merge approval and does not request a Generated by autopilot-pr-triage-worker. This comment is AI-generated and may contain errors. |
…ass (#2893) * Initial plan * build(deps): bump setuptools to 83.0.0 in uv lockfile Co-authored-by: sergio-sisternes-epam <207026618+sergio-sisternes-epam@users.noreply.github.com> * Fix skills subset installs for manifestless Git collections (#2891) * Initial plan * Fix manifestless skill collection subset resolution Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> * test: restore complete architecture guard mutation coverage (#2892) * Initial plan * test: cover missing architecture owner guard mutations Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> * fix(registry): exact version selectors must match published build metadata (#2894) * fix(registry): exact version selectors must match published build metadata A version selector with no range operator (e.g. 1.0.2+fa163e16) was routed through semver range matching, which ignores build metadata in every comparison. Two published builds sharing the same major.minor.patch (e.g. 1.0.2+fa163e16 and 1.0.2+863e11af) tied under that comparison, so the resolver could silently return a different build than the one requested. Check for an exact string match against the published version list before falling into range matching. Real ranges (^, ~, >=, wildcards) are unaffected, since none of them can ever equal a published version string literally. Fixes #2877 * test(registry): give each build-metadata test its own matching tarball Addresses review feedback: the fixture previously reused one tarball (declared apm.yml version 1.0.2, no build metadata) for both published VersionEntry builds. Build a distinct tarball per build whose apm.yml version matches its VersionEntry, and return the right bytes for the requested version, so the test stays accurate if package validation later cross-checks the extracted version against the resolved one. * fix(install): fail loudly when a package deploys to no target (closes #2796) (#2806) * fix(install): fail target-excluded plugin no-ops Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: preserve agent plugin recovery refs Addresses panel follow-ups to keep Agent Plugin target-exclusion recovery commands pinned to the selected ref, document the breaking no-op contract, and add real CLI lifecycle coverage for total no-op failure plus mixed-install success. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: update plugin target no-op lifecycle Addresses the CI regression from the legacy exit-0 expectation by rewriting the Agent Plugin non-Copilot target test for issue #2796: a total target-exclusion no-op now fails and commits no durable state. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: ground plugin recovery hints in declared skills Fold #2806 advisory follow-ups: select an inventoried skill directory, quote POSIX command operands, assert mixed-install skill bytes, and document dry-run behavior. Drop release-note duplicates resurrected while incorporating main. Mutation probes reject missing outcome, inventory and quoting guards. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: Add WinGet method installation (#2520) * docs: Add WinGet method installation * docs: clarify WinGet installation and upgrades Address review follow-ups with exact registry selection, prerequisites, separate Windows examples, and matching upgrade guidance. Keep Scoop and the contributor's additive distribution intent. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore(deps): bump svgo from 4.0.2 to 4.1.0 in /docs (#2914) Bumps [svgo](https://github.com/svg/svgo) from 4.0.2 to 4.1.0. - [Release notes](https://github.com/svg/svgo/releases) - [Commits](svg/svgo@v4.0.2...v4.1.0) --- updated-dependencies: - dependency-name: svgo dependency-version: 4.1.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(deps): preserve GitLab sparse-fetch transport (#2939) * fix(deps): preserve GitLab sparse-fetch transport Execute the shared transport plan using prepared remotes and per-attempt authentication. Gate REST on executed effective HTTPS, isolate live checkout identities, and add real-Git, architecture and mutation regression proof. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(spec): bind GitLab sparse fetch to port and cache requirements Reuse the real-Git transport contract as executable evidence for req-sc-013 and req-rs-016, rather than waiving the Mode B conformance gate. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(spec): regenerate GitLab sparse conformance evidence Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(deps): align legacy REST fixtures with selected Git attempts Configure a real strict HTTPS transport plan and a typed Git failure in REST tests, and include the new sparse-plan rule in the frozen architecture inventory. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(deps): fold bounded sparse transport review feedback Address CEO docs and diagnostics follow-ups on PR #2939: distinguish requested SSH from effective Git rewrites, correct packaged REST guidance, repair fallback recovery advice, and expose admitted protocol switches. Add a warning regression and isolated mutation proof without changing validation auth or other provider policy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(deps): fold GitLab sparse Copilot regression fixes Fix both legacy integration REST fixtures to execute a real HTTPS selector plan and raise only typed Git failures. Probe symlink capability rather than skipping Windows unconditionally, and qualify the canonical sparse-fetch credential documentation. Addresses Copilot review 5167472317 without changing validation auth or shared selector dedup semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(deps): align clone fallback warning regression CI recovery 1: the shared custom-port warning now correctly explains disabling all fallback configuration sources and points at the live docs route. Update its older clone consumer assertion to this reviewed wording without changing runtime behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(init): onboard existing local packages without rewriting source (#2937) * feat(init): onboard existing local packages without conversion Build on the read-only discovery work from #2857 while keeping apply metadata-only. Prove discover, declare, install, rerun, and collision protection through the existing APMLifecycle runner. Co-authored-by: Ron Izraeli <35386615+chkp-roniz@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(onboarding): bind native collision safety to local priority Cover the existing req-pr-002 local-priority contract with the native-skill collision regression and assert its recorded diagnostic. No normative requirements or specification prose change. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(onboarding): reject existing collisions and report successful targets Reject conflicting pre-existing dependency slots before applying any manifest delta. Report native skill metadata from the first successful target, preserving skipped author-owned destinations. Refresh owned-collision fixtures and the architecture rule inventory. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(onboarding): preserve global handoff and discovery boundaries Addresses scoped panel follow-ups: preserve user scope in the separate install hint, document declined consent, and defend the existing init discovery facade and target-selection boundary without expanding admission or installation behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Ron Izraeli <35386615+chkp-roniz@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore(deps): bump astro from 7.2.7 to 7.3.2 in /docs (#2922) Bumps [astro](https://github.com/withastro/astro/tree/HEAD/packages/astro) from 7.2.7 to 7.3.2. - [Release notes](https://github.com/withastro/astro/releases) - [Changelog](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md) - [Commits](https://github.com/withastro/astro/commits/astro@7.3.2/packages/astro) --- updated-dependencies: - dependency-name: astro dependency-version: 7.3.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump smol-toml from 1.6.1 to 1.8.0 in /docs (#2942) Bumps [smol-toml](https://github.com/squirrelchat/smol-toml) from 1.6.1 to 1.8.0. - [Release notes](https://github.com/squirrelchat/smol-toml/releases) - [Commits](squirrelchat/smol-toml@v1.6.1...v1.8.0) --- updated-dependencies: - dependency-name: smol-toml dependency-version: 1.8.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: establish issue-first contribution and governance policy (#2954) * docs: establish issue-first contribution and governance policy Implement the approved Phase 1 scope in #2953. Separate human scope approval from automated recommendations, document the maintainer roster and progression, and preserve technical reference material in the development guide. Live automation and backlog migration remain later phases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: fix rendered OpenAPM specification link Use Astro's openapm-v01 route rather than the source filename spelling. Fix the broken link reported by the Deploy Docs workflow for #2954. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(triage): make automated recommendations advisory (#2956) * docs: establish issue-first contribution and governance policy Implement the approved Phase 1 scope in #2953. Separate human scope approval from automated recommendations, document the maintainer roster and progression, and preserve technical reference material in the development guide. Live automation and backlog migration remain later phases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: fix rendered OpenAPM specification link Use Astro's openapm-v01 route rather than the source filename spelling. Fix the broken link reported by the Deploy Docs workflow for #2954. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(triage): make automated recommendations advisory Constrain workflow outputs to classification and processing metadata, retain legacy deduplication, and preserve human scope approval in direct consumers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: define issue-backed roadmap and release planning (#2959) * docs: establish issue-first contribution and governance policy Implement the approved Phase 1 scope in #2953. Separate human scope approval from automated recommendations, document the maintainer roster and progression, and preserve technical reference material in the development guide. Live automation and backlog migration remain later phases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: fix rendered OpenAPM specification link Use Astro's openapm-v01 route rather than the source filename spelling. Fix the broken link reported by the Deploy Docs workflow for #2954. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(triage): make automated recommendations advisory Constrain workflow outputs to classification and processing metadata, retain legacy deduplication, and preserve human scope approval in direct consumers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: define issue-backed roadmap and release planning Closes #2958. Document the approved planning model; live Project rollout remains separately gated. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(governance): require human scope and add neutral eligibility evidence (#2964) * fix(governance): require human scope and add neutral eligibility evidence Refs #2960. Keep implementation authority human, make daily docs discovery-only, and deploy compatible triage consumers with regression coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(governance): make workflow trust and manual scope boundaries explicit Use a verified literal default-branch checkout and bind policy to its actual commit. Remove remaining docs workflow label-ratification instructions; keep companion work outside unattended runs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix: harden governance event and child-wave boundaries Address the six bounded review contracts: default-branch entrypoints, fresh child-wave confirmation, trusted gh resolution, complete approval records, visible references, and bounded metadata reads. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(git-env): skip the HTTP header probe for non-HTTP effective URLs (#2906) * fix(git-env): skip the HTTP header probe for non-HTTP effective URLs An `insteadOf` rule that rewrites the fetched HTTPS URL to SSH, such as `url."git@github.com:".insteadOf = https://github.com/`, made every private dependency download fail on the authenticated retry. `_validated_git_url_rewrite_policy` asked whether an HTTP `extraHeader` applied to the effective URL. With an SCP-style target that probe ran `git config --get-urlmatch http.extraHeader git@github.com:owner/repo`, which git rejects with `invalid URL scheme name or missing '://' suffix` and exit status 128, so the probe raised `GitUrlRewriteProbeError`. An HTTP header can never reach a non-HTTP transport, so the answer is already known: report no authorization and do not spawn the probe. The remaining non-zero branch now names the exit status instead of only saying the probe failed. Fixes #2898 * docs(changelog): reference the pull request number * fix(git-env): keep malformed rewrite targets on the wrapped safety error The non-HTTP guard added in the previous commit was the first urlsplit applied to the effective URL, and it is evaluated as an argument to validate_resolved_git_url_rewrite -- so before that function's try/except. An insteadOf rule whose replacement carries unbalanced brackets, such as url."https://[::1/".insteadOf, therefore surfaced a raw ValueError("Invalid IPv6 URL") instead of the module's "Unable to verify Git URL rewrite safety", and the CPython message for a bracketed non-address embeds the host unredacted. Guarding the scheme lookup cannot fail open: both callers pass the same URL straight to validate_resolved_git_url_rewrite, which re-splits it inside its try and raises the wrapped error. * fix: complete SCP rewrite consumer coverage and recovery Address panel follow-ups on PR #2906 with real Git config resolver and authenticated-retry regressions, HTTP origin controls, and probe-specific recovery guidance. Preserve unsafe-rule recovery for proven policy failures and synchronize authentication documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: publish the active issue-backed roadmap (#2988) Publish Project 2304 from the README and contribution entry points, replace pending-rollout prose, and preserve issue-owned scope and milestone-owned release planning. Refs #2960 Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(uninstall): preserve unmanaged skills with an empty inventory (#2947) * fix(uninstall): preserve unmanaged skills with an empty inventory * docs(changelog): link unmanaged skill cleanup fix * test(ci): repair stale daily release smoke fixtures (#2987) Cover the two registered owner guards, exercise GitLab REST through real transport selection, and align Windows fixtures with canonical home/path and deployed-file hash contracts. Preserve production behavior and strengthen regression witnesses for #2965. Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(cache): pin core.autocrlf=false on GitCache checkouts (#2982) * fix(cache): pin core.autocrlf=false on GitCache checkouts (closes #2971) Git-subpath materialization went through GitCache without the CRLF pin that bare_cache already set, so Windows hosts with system core.autocrlf=true recorded non-portable content_hash values. Add a -c pin that outranks env-frozen host config, persist it on the checkout, and rematerialize unpinned shards. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(changelog): cite #2982 for GitCache autocrlf pin Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(cache): heal GitCache autocrlf pin under shard lock Defer unpinned SHA-valid eviction until _create_checkout holds the shard lock, parse the local core.autocrlf key, fail closed on land races, and document legacy lockfile regeneration. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(cache): isolate autocrlf host fixture and fail closed Drop inherited GIT_CONFIG_NOSYSTEM/PARAMETERS before the hostile-host regression, assert system autocrlf=true, document lock --update recovery, and reject unremovable unpinned shards. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: release v0.31.0 (#2989) Bump pyproject.toml and the apm-cli uv.lock entry to 0.31.0, and curate the dated changelog for the minor release. Current CI lint mirror passes locally; dependency versions, public registry URLs, and hashes remain unchanged. Post-merge: tag v0.31.0 to trigger the release workflow. Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): origin-aware skills with CODEOWNERS-safe review (#3003) * feat: add ORIGIN x INTENT autopilot for triage, delivery, and review Replay the actor-aware autopilot surface onto origin/main as one commit: unattended runs never assign; actor-session delivery assigns the working user; standalone review requests that user as reviewer. Schedulers own the queue scripts and fan-out; workers advise or implement one item. Keep CODEOWNERS additive and require full conversation context before new advice. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): align tags and delivery with human-scope governance Keep triage/requested as the only request trigger. status/needs-triage stays human state. Delivery still queues on status/accepted, then probes scripts/governance/eligibility.cjs and requires fresh confirmation. Unattended ORIGIN never implements. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): turn monolith orchestrators into sequencing aliases apm-issue-autopilot and batch-bug-shepherd no longer implement. They dispatch the canonical schedulers in-session, with a hard stop so triage advice is not implementation permission. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): treat FANOUT_LIMIT as concurrency, not batch size Schedulers must persist and drain the full helper-selected list, refilling a slot when it returns. Two slots is parallelism only. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): stop spam-skipping bug forms; workers own writes Sweep markup strip no longer lets a heading eat the rest of the body, so valid GitHub bug forms stay eligible. Issue and PR triage workers own comments and processing labels; schedulers only queue and fan out. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): add worker activation card with optional writes Issue-triage worker declares activation_card: on. Writes default on; write: off returns the template without commenting or labeling. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): move PR-review writes off the scheduler PR-review scheduler only queues and fans out. Reviewing sessions own comments, labels, and the actor-session @me reviewer request. The composed worker gets an activation card with write default on. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): gate PR review on panel-review Unfiltered open-PR listing queued every pull request. Fresh review now requires the panel-review label or an explicit named list. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): require status/accepted before PR review panel-review only requests a pass. Without status/accepted on the PR or a linked issue, the reviewing session comments, clears the request label, and stops. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): rename review panel; silent unaccepted stop Rename apm-review-panel to autopilot-pr-review-panel and keep the old name as a compatibility alias. Scheduler, worker, and panel all stop when status/accepted is missing. Scheduler and worker leave no comment; panel/worker may clear panel-review. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): review-worker is advisory; merge-worker is drive-to-merge Keep autopilot-pr-review-scheduler advisory-only. It composes autopilot-pr-review-worker and never spawn autopilot-pr-merge-worker. Summon merge-worker by name. Old panel names stay aliases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): require Autogenesis activation cards on canonical skills Enter before work, Exit after. Do not load Autogenesis path modules. Schedulers are write off; workers default write on. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): drop Autogenesis wording from activation cards Keep Enter/Exit cards. Do not name the source discipline. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): declare activation_card on for every autopilot skill Aliases and canonical skills both set the flag. Canonical skills still own the Enter/Exit card body. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: add maintainer map for autopilot skills Internal package map only. Not product documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): nest skill packages under packages/autopilot Keep leaf package names. Move the maintainer map to packages/autopilot/README.md. Point pr-description-skill deps up one more directory. Leave .agents/skills/ deploy layout flat. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): require scheduler queue tables with labels Schedulers must emit keep-set and drop-set rows (number, kind, labels, rationale, slot) before any spawn. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): invocation is harness, not origin Copilot App, local, Cloud, and Remote Agent fill actor-session. agentic-workflow is only gh-aw / Actions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): exclude completed-advice from triage sweeps Sweep fetch skips triage/recommended and status/triaged at GitHub so already-advised open issues and PRs are not re-listed. Do not write status/triaged. Named requests still fetch the one item. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): name worker sessions Domain stage #n Issue triage #2993, PR triage #1017, Issue delivery #2902, PR review #2741. No GitHub title. Do not rename in-flight sessions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Keep issue-triage JSON internal, not on GitHub comments. The public advisory is prose plus the HTML receipt. Workers still fill schema_version 2 JSON for the parent Exit, not the issue thread. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Make triage JSON receipts optional, default off. Enter/Exit cards take json: off|on. Omitted or unknown is off, not a missing-field stop. json: on stays an internal payload; GitHub comments stay prose. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Stop the Triage Panel AW from requiring a JSON comment tail. Pass json: off into autopilot-issue-triage-worker. GitHub comments stay prose plus the HTML receipt. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Route the PR Review Panel AW through the review scheduler. Load autopilot-pr-review-scheduler (write off) then run autopilot-pr-review-worker in-thread. Do not compose the merge worker. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Auto-defer PRs with no accepted issue and thank the author. PR triage writes status/deferred unless a same-repo linked issue is status/accepted, and asks the author to open an issue first. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Queue accepted PRs for advisory review without a named list. Unsteered PR review now unions panel-review with status/accepted on the PR, then still applies the accepted gate and CODEOWNERS last-comment conditions. Named list is not required when a maintainer already accepted the PR. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Deliver accepted issues even when the author is a bot. status/accepted from a CODEOWNER is the queue gate. Author type is not a drop reason. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Remove autopilot compatibility alias stubs. Keep the nine canonical autopilot-{domain}-{stage}-{role} packages. Drop the 22 installable aliases, retarget tests to merge-worker and delivery, and refresh the lockfile. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: retarget leftover alias names to canonical autopilot skills PRINCIPLES.md, delivery/merge worker assets, and the cut-release eval note now name autopilot-{domain}-{stage}-{role} only. Historical CHANGELOG entries stay as written. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * style: ruff-format autopilot unit tests after main merge Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: refresh lock deployment hashes after alias-name retarget Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): align review sweep, auto-defer, and lock orphans Copilot App queue-open now unions panel-review with status/accepted on the PR. PR triage auto-defers only when neither the PR nor a linked issue is accepted. Drop deleted alias packages from the lockfile and retarget merge-worker eval fixtures. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(lock): rewrite deployed test-coverage-expert instruction link Install replay retargets the relative markdown link from .github/agents to .apm/instructions. The committed copy still used the source-relative path, which failed APM Self-Check drift. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): sole-assignee claim and trusted gh lookup Actor-session delivery continues only when @me is the sole human assignee after add, and re-checks before implement or PR. Triage queue helpers resolve gh through get_gh_executable so a project-controlled binary is never used. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * perf(cli): lazy-load heavyweight command modules (#3001) * perf(cli): lazy-load heavyweight command modules Defer install, audit, pack, marketplace, uninstall, update, and prune until the matching verb is dispatched so apm --help, apm doctor, and apm config get no longer import those graphs. Closes #2996 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(changelog): link lazy CLI dispatch to #3001 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(cli): freeze lazy verbs and keep completion light PyInstaller cannot follow importlib string paths, so collect apm_cli.commands into hiddenimports. Complete from stubs, match stub short_help to the real command, and advertise doctor --help. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Co-authored-by: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com> * fix(alias): reject path-traversing dependency aliases — fixes #2900 (#2901) * fix(alias): reject path-traversing dependency aliases Aliases were only matched against a lax character regex, letting values like "..", "./x", or "foo/../bar" escape apm_modules at download and integrate time. Now validating every parsed alias through path_security's segment checks and guarding the resolved install path inside the download/integrate phases. Adds unit coverage for traversal and safe aliases. * fix(alias): surface friendly error for traversal aliases Wrap validate_path_segments in parse_alias_override so '.'/'..' aliases translate PathTraversalError into the existing allowed-character message instead of leaking a low-level technical error. Strengthen traversal tests to assert the friendly message. * test(alias): prove install-phase symlink escape is blocked A valid alias like 'safe-name' passes parse-time validation, but apm_modules_dir/safe-name can itself be a symlink pointing outside apm_modules_dir. ensure_path_within is the only guard that resolves symlinks before containment (download.py:65, integrate.py:622); this test proves the escape raises PathTraversalError and never writes outside the managed tree. * test(alias): trap ensure_path_within guards end-to-end at install tier The parser rejects traversal aliases (parse_alias_override), and the ensure_path_within containment guards exist at download.py:65 and integrate.py:622 as the defense-in-depth last line. But no test drove those guards through the real phase entry points -- the PR "Scenario 4" claim (install path can never escape apm_modules even if the parser is bypassed) was proven only at unit tier. Add install-tier regression traps that route malicious aliases through the actual phase run() functions: - tests/red_team/install/test_alias_path_escape.py * download.run() rejects a '..' traversal alias and a symlink that resolves outside apm_modules_dir via PathTraversalError, asserting no download bytes land. * integrate.run() rejects the same two vectors before materialization. * Safe-alias controls confirm no false positive. - tests/unit/test_registry_entry_alias_traversal.py * Covers the secondary parse_registry_object_entry alias validation (registry_entry.py:86): regex layer (%2e%2e) and validate_path_segments layer ('..', 'pkg/..'), plus a safe-alias affirmative control. * Refactor install path handling for dependencies Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix(alias): centralize safe destinations without restricting sources Address the PR #2901 panel and Copilot follow-ups: route all alias ingress and materialization through existing owners, reject root-equal destinations, preserve local sibling sources, and defend real reinstall metadata and hashes with regression and architecture tests. Include actionable diagnostics and migration guidance. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(alias): preserve normalized roots and legacy cache preflight Address round-two architecture/security and lifecycle findings. Compare both roots through path_security, give safe alias recovery guidance, and preserve existing legacy-plugin validation before alias-aware resolution can normalize cached files. Main passes the legacy missing-metadata cases; added preflight keeps that behavior. Windows prefix and legacy-preflight mutation controls fail with guards removed. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(alias): preserve remote source anchors and cache replacement Keep authenticated remote coordinates separate from flat aliases. Inject the existing read-only legacy cache admission at actual reuse after canonical fetch decisions, not preparation; retain same-ref failure and transactional replacement. Extend real resolver and CLI lifecycle contracts with aliased remote siblings and invalid-cache ref changes. Mutation controls detect both source-anchor regression and misplaced or missing admission. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(alias): preserve placement and current ref replay after install Continue the existing PR #2901 CI recovery without resetting its run. Preserve the recovered implementation and review folds: durable alias projection, contained alias scanning, specification conformance, and current-remote ref observations after successful checkout. Original contributor and follow-up commits remain in the lineage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(cache): exercise stale bare fallback under corrupt receipts The mutation gate showed the previous fixture passed even when receipt handling was removed because no bare-cache directory existed. Materialize the canonical shard directory so the stale-ref fallback is reachable and the regression fails without the receipt guard. Production code is unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(lockfile): declare absent alias in dev dependency fixtures Continue CI recovery2 after Linux shard2 exposed four generic Mock dependency references whose undeclared alias attribute became another Mock. Model the real unaliased DependencyReference default explicitly instead of weakening production alias validation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(spec): preserve published alias schema identities Keep existing public v0.1 schemas byte-identical and select independent v0.1.41 schemas for alias validation. Accept the new exact manifest ID through the existing contract owner while retaining old-ID compatibility and fail-closed unknowns. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(alias): clarify compatibility and recovery after main integration Fold specification editorial fixes, keep the unshipped security note under Unreleased, document schema opt-in compatibility, and defend actionable diagnostics with regression assertions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(ci): repair advisory locks and platform regressions (#3021) * fix(ci): repair advisory locks and platform regressions Regenerate advisory workflow metadata without changing runtime pins. Preserve root-local discovery scope during scratch drift replay and make the Windows alias fixture assert the on-disk directory name. Add source-freshness and replay regression coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(ci): honor pinned workflow compiler and harden regression fixtures Recompile PR review with gh-aw v0.87.8 and verify the generated banner against the repository pin. Set explicit package deployment defaults and assert resolver initialization, isolate symlink-only prerequisites, and prove workflow hashes normalize LF, CRLF, and CR input. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore(deps): bump gitpython from 3.1.58 to 3.1.59 (#2921) Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.58 to 3.1.59. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](gitpython-developers/GitPython@3.1.58...3.1.59) --- updated-dependencies: - dependency-name: gitpython dependency-version: 3.1.59 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump js-yaml from 4.3.1 to 4.3.2 in /docs (#2920) Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.3.1 to 4.3.2. - [Changelog](https://github.com/nodeca/js-yaml/blob/4.3.2/CHANGELOG.md) - [Commits](nodeca/js-yaml@4.3.1...4.3.2) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 4.3.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump devalue from 5.8.1 to 5.9.2 in /docs (#3019) Bumps [devalue](https://github.com/sveltejs/devalue) from 5.8.1 to 5.9.2. - [Release notes](https://github.com/sveltejs/devalue/releases) - [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md) - [Commits](sveltejs/devalue@v5.8.1...v5.9.2) --- updated-dependencies: - dependency-name: devalue dependency-version: 5.9.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(build): support setuptools 83 in binary packaging Require PyInstaller 6.17.0 and lock its minimum compatible hooks to avoid altgraph importing the removed pkg_resources module. Preserve the setuptools 83.0.0 security upgrade. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergio-sisternes-epam <207026618+sergio-sisternes-epam@users.noreply.github.com> Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> Co-authored-by: Nadav Yogev <nadavy@jfrog.com> Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Gijs Reijn <26114636+Gijsreyn@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ron Izraeli <35386615+chkp-roniz@users.noreply.github.com> Co-authored-by: Arnaud <arnaudoisel@users.noreply.github.com> Co-authored-by: Marco Frömbgen <23717573+mfroembgen@users.noreply.github.com> Co-authored-by: Sergio Sisternes <sergio_sisternes@epam.com> Co-authored-by: Daniel <47431549+Danvs60@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Merge current main and remove execution-runtime propagation, CA snapshots, ownership markers, and managed bootstrap refresh. Keep additive trust in the existing TLS authority, cover Requests and stdlib fallback, and preserve explicit replacement and opt-out behavior. Validate real private-CA installs and unchanged child trust; align documentation with the October 2 approval for microsoft#2034.
|
Thanks Daniel Meppiel (@danielmeppiel). Pushed
The PR is conflict-free against upstream The six new CI/docs/CodeQL/spec/merge/NOTICE workflows require maintainer approval. Could you approve those runs and re-review this revision? The |
Description
APM_EXTRA_CA_BUNDLEadds corporate PEM certificates to APM's own package-management HTTPS while retaining its normal default trust roots. This lets a private registry or HTTPS proxy work without replacing the complete Requests trust set or changing the machine trust store.Trust selection remains in
core/tls_trust.py:REQUESTS_CA_BUNDLEtakes precedence overCURL_CA_BUNDLE; either retains replacement semantics and suppresses OS/additive injection.APM_DISABLE_TRUSTSTOREdisables OS/additive trust without removing an explicit replacement bundle.The bundle is validated once in memory. Failed publication restores the previous TLS state. The fallback stays inside the APM process; it does not create certificate files or derive environment variables for children. Hardened package-lifecycle Sessions retain explicit Requests/curl replacement settings while keeping
trust_env=False.Issue and approved scope
Fixes #2034 within the approved package-management scope, recorded on October 2. Review contact: Daniel Meppiel (@danielmeppiel).
This revision removes the earlier execution-runtime expansion: Python/Node propagation, snapshot directories and ownership markers, nested-shell machinery, and managed-runtime refresh. The child bootstrap, script runner, and
llmruntime now match upstream. Existing OS-trust bootstrap behavior is preserved.APM_EXTRA_CA_DIR, native Git/Rust TLS configuration, machine trust-store changes, and disabling verification remain outside this contribution.TLS troubleshooting, environment-variable reference, install diagnostics, enterprise guidance, and packaged
apm-usageguidance describe the narrowed behavior and precedence. The changelog entry is under Unreleased; released history is preserved.Type of change
Testing
Windows / Python 3.12.13:
The real source CLI installs an actual package from a private-CA loopback HTTPS registry. Ten fresh-project cases cover both normal OS trust and forced truststore unavailability: an independent default-root control, rejection without the extra CA, private-CA success, default-root retention with the extra CA, and rejection when an explicit replacement omits the default root. Successful installs verify metadata/download requests, package bytes, lockfile, and deployed instructions. The fixture uses synthetic roots and test-process certifi seeding, with no machine trust edits or transport/resolver mocks.
Additional real TLS checks cover Requests and stdlib fallback after import/publication failure, default-root retention, rejection of unrelated roots and wrong hostnames, startup failure for invalid input, and real
apm runchildren receiving no derived additive trust. Existing runtime/bootstrap, frozen-hook, lifecycle, CLI, and precedence regressions are included.This is hermetic compatibility evidence, not a claim of validation in a particular enterprise deployment. The branch includes upstream
mainat18c4c43c. Hosted checks and maintainer review remain separate gates.Spec conformance (OpenAPM v0.1)