Keep native maintenance checks compiling and command facts clean

Completed PR2825 CI reports Windows Unix-type compilation failures and three Prettier fixture failures. Compile the existing Linux-only MSP daemon fixture only on Linux and format the unchanged frontend assertions. Separate successful CLI stdout from retained stderr diagnostics so Compose warnings cannot corrupt container identities, ports or bootstrap facts; add three executable controls without changing deadlines or acceptance gates.

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-10-11 21:09:21 +01:00
parent b737fb1a3d
commit a6437f885f
5 changed files with 70 additions and 16 deletions
@@ -7781,3 +7781,20 @@ or failed parsers, failed transport with a plausible body, redirects, pins and
downgrade refusal. Existing extracted-function tests include the shared selector.
These are source-level selection controls, not native installation, published
release acceptance or a repair to a third-party community helper.
### Combined-batch native fixture reconciliation (11 October 2026)
The real provider-MSP startup fixture is Linux-only at compile time, matching
its existing Linux transport admission. Its cloud-control-plane import must not
pull Unix filesystem types into Windows installer test compilation. Windows
installer and lifecycle tests remain enabled; the startup fixture still runs in
the Linux process proof and hosted Compose job.
Successful command stdout alone supplies container identities, published ports
and bootstrap facts. Stderr warnings remain logged evidence, never arguments to
the next Docker command. Failure diagnostics retain both streams and the original
nonzero exit. `TestProviderMSPStartupCommandSeparatesDiagnostics` checks three
consumer shapes with controlled successful stderr; it is not Docker acceptance.
Hosted mounted-secret/readiness/persistence/refusal/cleanup checks remain required.
Frontend fixture reformatting retains all assertions and changes no runtime UI.
@@ -25,7 +25,9 @@ describe('agent token-file help in the shipped Markdown renderer', () => {
expect(link?.getAttribute('href')).toBe(`#${id}`);
expect(link?.hasAttribute('data-doc-link')).toBe(false);
expect(link?.hasAttribute('target')).toBe(false);
expect(article.querySelector(`#${id}`)?.textContent).toBe('Token-file format is not shell syntax');
expect(article.querySelector(`#${id}`)?.textContent).toBe(
'Token-file format is not shell syntax',
);
expect(guide).toBe(
readFileSync(path.join(repoRoot, 'frontend-modern/public/docs/UNIFIED_AGENT.md'), 'utf8'),
);
@@ -55,10 +57,15 @@ describe('agent token-file help in the shipped Markdown renderer', () => {
].entries()) {
expect(rows[index].textContent).toContain(phrase);
}
const text = parts.map((element) => element.textContent).join(' ').replace(/\s+/g, ' ');
const text = parts
.map((element) => element.textContent)
.join(' ')
.replace(/\s+/g, ' ');
expect(text).toContain('not the value, length, hint, screenshot or file');
expect(text).toContain('Do not print, source, upload or edit the installed token file');
expect(text).toContain('not proof of accepted reporting');
expect(parts.some((element) => element.matches('pre') || element.querySelector('pre'))).toBe(false);
expect(parts.some((element) => element.matches('pre') || element.querySelector('pre'))).toBe(
false,
);
});
});
@@ -5,7 +5,8 @@ import { describe, expect, it } from 'vitest';
import { renderDocMarkdown } from '../docMarkdown';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../..');
const guide = (name: string): string => readFileSync(path.join(root, 'frontend-modern/public/docs', `${name}.md`), 'utf8');
const guide = (name: string): string =>
readFileSync(path.join(root, 'frontend-modern/public/docs', `${name}.md`), 'utf8');
const article = (name: string): HTMLElement => {
const element = document.createElement('article');
element.innerHTML = renderDocMarkdown(guide(name), name);
@@ -15,7 +16,11 @@ const section = (): HTMLElement => {
const heading = article('FAQ').querySelector('#can-i-disable-alerts-for-specific-metrics');
expect(heading).not.toBeNull();
const element = document.createElement('section');
for (let next = heading!.nextElementSibling; next && !/^H[1-6]$/.test(next.tagName); next = next.nextElementSibling) {
for (
let next = heading!.nextElementSibling;
next && !/^H[1-6]$/.test(next.tagName);
next = next.nextElementSibling
) {
element.appendChild(next.cloneNode(true));
}
return element;
@@ -28,11 +33,14 @@ describe('shipped alert Off FAQ', () => {
expect(text).toContain('not every default has a per-resource control');
expect(text).toContain('save, then reopen the editor');
expect(element.querySelectorAll('li')).toHaveLength(4);
for (const phrase of ['does not hide its readings, stop collection',
'explicit threshold can remain active', 'Already queued notifications',
for (const phrase of [
'does not hide its readings, stop collection',
'explicit threshold can remain active',
'Already queued notifications',
'Patrol findings are separate from threshold alerts',
'when the corresponding alert default is Off',
'Do not induce an alert, send another Test or retry the queue']) {
'Do not induce an alert, send another Test or retry the queue',
]) {
expect(text).toContain(phrase);
}
expect(element.querySelector('pre')).toBeNull();
@@ -42,7 +50,10 @@ describe('shipped alert Off FAQ', () => {
it('routes the two independent warning paths to real shipped headings', () => {
const links = [...section().querySelectorAll('a')];
expect(links).toHaveLength(2);
expect(links.map((link) => link.textContent)).toEqual(['how Patrol works', 'ordinary notification checks']);
expect(links.map((link) => link.textContent)).toEqual([
'how Patrol works',
'ordinary notification checks',
]);
for (const link of links) {
const [name, fragment] = link.getAttribute('href')!.replace('/docs/', '').split('#');
expect(article(name).querySelector(`#${fragment}`)).not.toBeNull();
@@ -657,9 +657,7 @@ describe('docsLinks', () => {
/if !reportCallerMayUseAI\(ctx\) \{\s*return nil, nil, h\.resolveExistingFindings\(ctx\)\s*\}\s*return h\.narratorResolver\(ctx\)/,
);
expect(resolver.match(/h\.narratorResolver\(/g)).toHaveLength(1);
expect(fleet).toMatch(
/_, fleetNarrator, findings := h\.resolveNarrator\(ctx\)/,
);
expect(fleet).toMatch(/_, fleetNarrator, findings := h\.resolveNarrator\(ctx\)/);
expect(fleet.match(/h\.resolveNarrator\(/g)).toHaveLength(1);
});
@@ -1,3 +1,5 @@
//go:build linux
package installtests
import (
@@ -265,12 +267,17 @@ func startupCommand(t *testing.T, env []string, dir, program string, args ...str
defer cancel()
cmd := exec.CommandContext(ctx, program, args...)
cmd.Dir, cmd.Env = dir, env
output, err := cmd.CombinedOutput()
if err != nil {
var stdout, stderr bytes.Buffer
cmd.Stdout, cmd.Stderr = &stdout, &stderr
if err := cmd.Run(); err != nil {
// Environment and licence contents are never diagnostic output.
t.Fatalf("%s command failed: %v\n%s", filepath.Base(program), err, output)
t.Fatalf("%s command failed: %v\n%s\n%s", filepath.Base(program), err, stdout.String(), stderr.String())
}
return string(output)
if stderr.Len() != 0 {
// Compose warnings are evidence, not container IDs, ports or CLI facts.
t.Logf("%s diagnostics: %s", filepath.Base(program), stderr.String())
}
return stdout.String()
}
func startupRefusal(t *testing.T, env []string, dir, want, program string, args ...string) {
@@ -384,3 +391,17 @@ func startupFacts(output string) map[string]string {
}
return facts
}
// Compose may warn on stderr about optional unset variables even when it
// succeeds. Never pass those diagnostics as the next docker exec identity.
func TestProviderMSPStartupCommandSeparatesDiagnostics(t *testing.T) {
for _, value := range []string{"synthetic-container-id", "127.0.0.1:8443", "provider_msp_bootstrap_ok=true"} {
t.Run(value, func(t *testing.T) {
output := startupCommand(t, []string{"PATH=" + os.Getenv("PATH")}, t.TempDir(), "sh", "-c",
`printf '%s\n' "$1"; printf 'optional variable warning\n' >&2`, "fixture", value)
if output != value+"\n" {
t.Fatalf("command facts include diagnostics: %q", output)
}
})
}
}