agentic-workflow-manager 9.22.0 → 9.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/src/commands/change/index.js +2 -2
  2. package/dist/src/commands/init.js +8 -4
  3. package/dist/src/commands/registry/add.js +9 -3
  4. package/dist/src/commands/sync.js +11 -5
  5. package/dist/src/commands/update.js +23 -12
  6. package/dist/src/core/changes/derive.js +6 -3
  7. package/dist/src/core/changes/git.js +1 -2
  8. package/dist/src/core/changes/worktree.js +15 -3
  9. package/dist/src/core/init/steps.js +3 -8
  10. package/dist/src/core/registries.js +20 -15
  11. package/dist/src/core/registry-git-errors.js +107 -0
  12. package/dist/src/core/registry-git.js +93 -0
  13. package/dist/src/core/registry-sync-report.js +74 -0
  14. package/dist/src/core/versioning.js +3 -6
  15. package/dist/src/index.js +5 -8
  16. package/dist/tests/commands/change/new.test.js +103 -57
  17. package/dist/tests/commands/change/validate.test.js +164 -108
  18. package/dist/tests/commands/changes/list.test.js +41 -22
  19. package/dist/tests/commands/job/gate-reconcile.test.js +13 -2
  20. package/dist/tests/commands/registry-sync-honesty.test.js +175 -0
  21. package/dist/tests/commands/sensors/exec.test.js +3 -1
  22. package/dist/tests/commands/update.test.js +8 -8
  23. package/dist/tests/commands/watch/supervisor-loop.test.js +21 -5
  24. package/dist/tests/core/changes/helpers.js +15 -3
  25. package/dist/tests/core/changes/list-paging.test.js +131 -110
  26. package/dist/tests/core/changes/list.test.js +133 -83
  27. package/dist/tests/core/changes/receipt.test.js +18 -6
  28. package/dist/tests/core/diagnostics/provider-checks.test.js +3 -0
  29. package/dist/tests/core/init/steps-registry-sync.test.js +6 -8
  30. package/dist/tests/core/registry-git.test.js +153 -0
  31. package/dist/tests/helpers/commit-seeded-registry.js +18 -0
  32. package/dist/tests/integration/codex-provider-isolated.test.js +7 -2
  33. package/dist/tests/integration/copilot-init-isolated.test.js +7 -4
  34. package/dist/tests/structural/active-documentation.test.js +0 -41
  35. package/dist/tests/structural/bundle-skill-reference-contract.test.js +0 -12
  36. package/dist/tests/structural/cli-reference-matches-commander.test.js +94 -0
  37. package/dist/tests/structural/native-release-artifacts.test.js +116 -107
  38. package/dist/tests/structural/sensor-documentation-contract.test.js +0 -47
  39. package/dist/tests/structural/sensor-portability-contract.test.js +0 -7
  40. package/dist/tests/structural/simple-git-v4-pin.test.js +49 -0
  41. package/package.json +2 -2
  42. package/prebuilds/darwin-arm64/secure_fs.node +0 -0
  43. package/prebuilds/darwin-x64/secure_fs.node +0 -0
  44. package/prebuilds/win32-arm64/secure_fs.node +0 -0
  45. package/prebuilds/win32-x64/secure_fs.node +0 -0
  46. package/dist/tests/structural/cloud-admission-docs-contract.test.js +0 -54
  47. package/dist/tests/structural/documentation-phase-is-mechanized.test.js +0 -29
  48. package/dist/tests/structural/operator-environments-docs-contract.test.js +0 -70
  49. package/dist/tests/structural/process-model-description-contract.test.js +0 -34
  50. package/dist/tests/structural/project-declared-sensors-docs-contract.test.js +0 -104
  51. package/dist/tests/structural/r4-plan-currentness-docs.test.js +0 -37
  52. package/dist/tests/structural/sensor-execution-optimization-docs-contract.test.js +0 -102
  53. package/dist/tests/structural/sensor-slice-decision-contract.test.js +0 -63
@@ -5,13 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const fs_1 = __importDefault(require("fs"));
7
7
  const path_1 = __importDefault(require("path"));
8
- const commander_1 = require("commander");
9
8
  jest.mock('@clack/prompts', () => ({
10
9
  log: { error: jest.fn(), success: jest.fn(), warn: jest.fn(), info: jest.fn() },
11
10
  }));
12
11
  const manifest_1 = require("../../src/commands/sensors/compatibility/manifest");
13
- const ledger_1 = require("../../src/commands/ledger");
14
- const sensors_1 = require("../../src/commands/sensors");
15
12
  const ROOT = path_1.default.resolve(__dirname, '../../..');
16
13
  const read = (file) => fs_1.default.readFileSync(path_1.default.join(ROOT, file), 'utf8');
17
14
  function documentedJson(files) {
@@ -35,26 +32,7 @@ function documentedV2Manifests(files) {
35
32
  && example.value.schemaVersion === 2)
36
33
  .map(example => example.value);
37
34
  }
38
- function helpFor(command) {
39
- const program = new commander_1.Command().name('awm');
40
- (0, sensors_1.registerSensorsCommand)(program);
41
- (0, ledger_1.registerLedgerCommand)(program);
42
- const [parent, child] = command.split(' ');
43
- return program.commands.find((entry) => entry.name() === parent)
44
- .commands.find((entry) => entry.name() === child).helpInformation();
45
- }
46
35
  describe('R3 canonical sensor documentation', () => {
47
- test.each([
48
- ['docs/framework.md', ['Static coverage', 'Empirical coverage', 'retrospective feedback loop']],
49
- ['docs/configuration.md', ['pack schema v2', 'legacy pack', 'compatible-unverified']],
50
- ['docs/project-setup.md', ['version-aware', 'hardening opt-in']],
51
- ['docs/runbook.md', ['awm sensors coverage --min', 'compatibility drift', 'orphaned asset']],
52
- ['docs/cli-reference.md', ['schemaVersion: 2', '--defect-class', '--min']],
53
- ['docs/architecture.md', ['compatibility resolver', 'bounded probe']],
54
- ])('%s owns its R3 subject', (file, phrases) => {
55
- const text = read(file);
56
- phrases.forEach((phrase) => expect(text).toContain(phrase));
57
- });
58
36
  test('parses every documented v2 sensor manifest example with the production parser', () => {
59
37
  const examples = documentedV2Manifests(['docs/configuration.md', 'docs/cli-reference.md']);
60
38
  expect(examples.length).toBeGreaterThan(0);
@@ -77,29 +55,4 @@ describe('R3 canonical sensor documentation', () => {
77
55
  schemaVersion: 2, pack: 'js-ts', sensors: { test: { enabled: true, variantId: 'npm-script' } },
78
56
  }, 'invalid full manifest')).toThrow();
79
57
  });
80
- test('documents exact Commander flags', () => {
81
- expect(helpFor('sensors coverage')).toContain('--min <count>');
82
- expect(helpFor('ledger add')).toContain('--defect-class <id>');
83
- const reference = read('docs/cli-reference.md');
84
- expect(reference).toContain('awm sensors coverage [--json] [--min <count>]');
85
- expect(reference).toContain('--defect-class <id>');
86
- });
87
- test('does not overstate the human coverage renderer or retrospective archive wiring', () => {
88
- const reference = read('docs/cli-reference.md');
89
- const runbook = read('docs/runbook.md');
90
- expect(reference).toMatch(/safe,\s+sanitized evidence references and safe cluster signatures/);
91
- expect(reference).toMatch(/never ledger\s+descriptions, raw ledger lines, or unsafe values/);
92
- expect(runbook).toContain('Run `awm sensors coverage --min 2` manually before archive');
93
- expect(runbook).toMatch(/Automatic\s+coverage-before-archive enforcement is delivered by the registry in T12/);
94
- expect(runbook).not.toContain('it automatically evaluates\ncoverage feedback');
95
- });
96
- test('keeps archival coverage manual until registry enforcement and scopes v2 binary resolution', () => {
97
- const framework = read('docs/framework.md');
98
- const osMatrix = read('docs/testing/os-matrix.md');
99
- expect(framework).toMatch(/manual operator step[\s\S]*until the registry delivers automatic enforcement in T12/i);
100
- expect(osMatrix).toMatch(/v2 local resolution modes use project-local `node_modules` or `.venv`\/`venv`\s+environments/i);
101
- expect(osMatrix).toMatch(/Windows `.cmd`\/`.bat` wrappers are rejected for structured v2\s+commands/i);
102
- expect(osMatrix).toMatch(/Legacy string\s+commands remain separate and retain their documented shell\/PATH semantics/i);
103
- expect(osMatrix).not.toContain('Sensors resolve their binaries on PATH');
104
- });
105
58
  });
@@ -24,13 +24,6 @@ describe('Publication B portable bootstrap contract', () => {
24
24
  expect(help).toContain('--reason <text>');
25
25
  expect(help).toContain('--dry-run');
26
26
  });
27
- it('documents schema v3, explicit migration, dry-run, and environment separation', () => {
28
- const reference = fs_1.default.readFileSync(path_1.default.join(root, 'docs/cli-reference.md'), 'utf8');
29
- expect(reference).toContain('awm sensors bootstrap [--mode project-sensors|native-gate|opt-out] [--reason <text>] [--dry-run]');
30
- expect(reference).toContain('schemaVersion: 3');
31
- expect(reference).toContain('never writes');
32
- expect(reference).toContain('each environment updates its own AWM installation separately');
33
- });
34
27
  it('keeps all documented v3 declarations free of machine registry paths', () => {
35
28
  const reference = fs_1.default.readFileSync(path_1.default.join(root, 'docs/cli-reference.md'), 'utf8');
36
29
  const examples = Array.from(reference.matchAll(/```json\s*\n([\s\S]*?)```/g), match => JSON.parse(match[1]));
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const CLI_ROOT = path_1.default.resolve(__dirname, '..', '..');
9
+ const FACTORY = 'src/core/registry-git.ts';
10
+ describe('simple-git v4 pin (#238)', () => {
11
+ it('pins simple-git exactly to 4.0.2', () => {
12
+ const pkg = JSON.parse(fs_1.default.readFileSync(path_1.default.join(CLI_ROOT, 'package.json'), 'utf8'));
13
+ expect(pkg.dependencies['simple-git']).toBe('4.0.2');
14
+ });
15
+ it('imports simple-git only from registry-git.ts via named simpleGit', () => {
16
+ const factory = fs_1.default.readFileSync(path_1.default.join(CLI_ROOT, FACTORY), 'utf8');
17
+ expect(factory).toMatch(/import\s*\{[^}]*\bsimpleGit\b[^}]*\}\s*from\s*['"]simple-git['"]/);
18
+ expect(factory).not.toMatch(/import\s+simpleGit\s+from\s*['"]simple-git['"]/);
19
+ const walk = (dir) => {
20
+ const out = [];
21
+ for (const ent of fs_1.default.readdirSync(dir, { withFileTypes: true })) {
22
+ const p = path_1.default.join(dir, ent.name);
23
+ if (ent.isDirectory())
24
+ out.push(...walk(p));
25
+ else if (ent.name.endsWith('.ts'))
26
+ out.push(p);
27
+ }
28
+ return out;
29
+ };
30
+ for (const file of walk(path_1.default.join(CLI_ROOT, 'src'))) {
31
+ const rel = path_1.default.relative(CLI_ROOT, file).replace(/\\/g, '/');
32
+ if (rel === FACTORY)
33
+ continue;
34
+ const text = fs_1.default.readFileSync(file, 'utf8');
35
+ expect(text).not.toMatch(/from\s*['"]simple-git['"]/);
36
+ expect(text).not.toMatch(/\bsimpleGit\s*\(/);
37
+ }
38
+ });
39
+ it('factory allowEnvironment is only GIT_TERMINAL_PROMPT and enables no allowUnsafe*', () => {
40
+ const factory = fs_1.default.readFileSync(path_1.default.join(CLI_ROOT, FACTORY), 'utf8');
41
+ expect(factory).toMatch(/allowEnvironment:\s*\[\s*['"]GIT_TERMINAL_PROMPT['"]\s*\]/);
42
+ expect(factory).not.toMatch(/allowUnsafe/);
43
+ // B1 / V1: factory must use the shared constant (not a duplicated literal).
44
+ expect(factory).toMatch(/timeout:\s*\{\s*block:\s*REGISTRY_GIT_TIMEOUT_MS\s*\}/);
45
+ expect(factory).toMatch(/export\s+const\s+REGISTRY_GIT_TIMEOUT_MS\s*=\s*60_?000\s*;/);
46
+ // SG-3: guarded env must be applied — deleting `.env(buildRegistryGitEnv())` must fail this pin.
47
+ expect(factory).toMatch(/\.env\(\s*buildRegistryGitEnv\(\)/);
48
+ });
49
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-workflow-manager",
3
- "version": "9.22.0",
3
+ "version": "9.22.1",
4
4
  "main": "dist/src/index.js",
5
5
  "bin": {
6
6
  "awm": "./dist/src/index.js"
@@ -55,7 +55,7 @@
55
55
  "picocolors": "^1.1.1",
56
56
  "picomatch": "4.0.7",
57
57
  "semver": "^7.7.4",
58
- "simple-git": "3.36.0"
58
+ "simple-git": "4.0.2"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@types/jest": "^30.0.0",
Binary file
Binary file
@@ -1,54 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const fs_1 = __importDefault(require("fs"));
7
- const path_1 = __importDefault(require("path"));
8
- /** CMD-DOCS — V-R4 (issue #215 documentation). */
9
- const repoRoot = path_1.default.resolve(__dirname, '../../..');
10
- /** Whitespace-normalized so re-wrapping the prose never breaks a pinned phrase. */
11
- const read = (relative) => fs_1.default.readFileSync(path_1.default.join(repoRoot, ...relative.split('/')), 'utf8').replace(/\s+/g, ' ');
12
- describe('issue #215 documentation contract (V-R4)', () => {
13
- const configuration = read('docs/configuration.md');
14
- it('documents .awm/admission.json with defaults, the git rule and the accepted risk', () => {
15
- expect(configuration).toContain('## Read-only admission observation (`.awm/admission.json`)');
16
- for (const name of ['node_modules', '.next', '.turbo', 'dist', 'build', 'coverage', '.venv', 'target'])
17
- expect(configuration).toContain(`\`${name}\``);
18
- expect(configuration).toContain('git-ignored and contains no tracked file');
19
- expect(configuration).toContain('**Accepted risk:**');
20
- expect(configuration).toContain('`admission-config-invalid`');
21
- expect(configuration).toContain('`readOnlyObservation`');
22
- expect(configuration).toContain('`awm plan admit` does not print it');
23
- });
24
- it.each([
25
- '250000',
26
- '1 GiB',
27
- '`read-only-mutation-detected`',
28
- '`read-only-observation-unavailable`',
29
- '`not-ignored`',
30
- '`contains-tracked`',
31
- '`git-unavailable`',
32
- '`.git` or `.awm`',
33
- 'never skipped',
34
- 'including any `.awm` or `.git` nested',
35
- 'regular file',
36
- '65536 bytes',
37
- ])('documents the observation limit, reason code or reserved-name rule %s', literal => {
38
- expect(configuration).toContain(literal);
39
- });
40
- it('points --verify-sensors in the CLI reference at the observation rules', () => {
41
- const doc = read('docs/cli-reference.md');
42
- expect(doc).toContain('configuration.md#read-only-admission-observation-awmadmissionjson');
43
- expect(doc).toContain('`ADMISSION_SENSORS_BLOCKED`');
44
- });
45
- it('states that the D-7 insteadOf recipe passes strict currentness', () => {
46
- const doc = read('docs/operations/cloud-and-platforms.md');
47
- expect(doc).toContain('`awm preflight --require-current`');
48
- expect(doc).toContain('`remote.origin.url`');
49
- expect(doc).toContain('--local');
50
- });
51
- it('describes the snapshot exclusions in the plan admit help', () => {
52
- expect(read('cli/src/commands/plan/index.ts')).toContain("'require an empirical sensor pass; read-only observation skips git-ignored build output (see .awm/admission.json)'");
53
- });
54
- });
@@ -1,29 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const fs_1 = __importDefault(require("fs"));
7
- const path_1 = __importDefault(require("path"));
8
- const ROOT = path_1.default.resolve(__dirname, '../../..');
9
- const read = (file) => fs_1.default.readFileSync(path_1.default.join(ROOT, file), 'utf8');
10
- describe('la fase de documentacion esta mecanizada, no solo enunciada', () => {
11
- it('CONSTITUTION.md enuncia la regla y nombra el marker', () => {
12
- const text = read('CONSTITUTION.md');
13
- expect(text).toMatch(/awm-docs-complete/);
14
- expect(text).toMatch(/post-implementation-docs/);
15
- });
16
- it('CONSTITUTION.md apunta al mecanismo, no lo reemplaza', () => {
17
- const text = read('CONSTITUTION.md');
18
- // debe citar el archivo que efectivamente hace cumplir la regla
19
- expect(text).toMatch(/plan-state\.ts/);
20
- expect(text).toMatch(/development-process/);
21
- });
22
- it('el enunciado NO es el unico lugar donde la fase existe', () => {
23
- // Si esto pasa solo por CONSTITUTION.md, la regla es decorativa.
24
- expect(read('cli/src/core/dashboard/plan-state.ts')).toMatch(/docsComplete/);
25
- expect(read('cli/src/core/dashboard/plan-state.ts')).toMatch(/docs_pending/);
26
- expect(read('cli/src/core/dashboard/sanitize.ts')).toMatch(/docsComplete/);
27
- expect(read('cli/src/commands/evidence/index.ts')).toMatch(/awm-docs-complete/);
28
- });
29
- });
@@ -1,70 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const fs_1 = __importDefault(require("fs"));
7
- const path_1 = __importDefault(require("path"));
8
- /**
9
- * CMD-SCAFFOLD-DOCS — RF-5.2 operator-environments documentation contract.
10
- * Asserts runbook + cli-reference document scaffold/doctor/env and state that
11
- * awm-cenco-infra-registry migration is out of scope (RF-5.2).
12
- */
13
- const repoRoot = path_1.default.resolve(__dirname, '../../..');
14
- const runbookPath = path_1.default.join(repoRoot, 'docs', 'runbook.md');
15
- const cliReferencePath = path_1.default.join(repoRoot, 'docs', 'cli-reference.md');
16
- const designPath = 'docs/plans/2026-10-12-operator-environments-design.md';
17
- function teamRegistriesSection(runbook) {
18
- const start = runbook.indexOf('## Team registries');
19
- expect(start).toBeGreaterThanOrEqual(0);
20
- const rest = runbook.slice(start);
21
- const nextH2 = rest.search(/\n## (?!Team)/);
22
- return nextH2 === -1 ? rest : rest.slice(0, nextH2);
23
- }
24
- function registriesSection(cliRef) {
25
- const start = cliRef.indexOf('## Registries & pinning');
26
- expect(start).toBeGreaterThanOrEqual(0);
27
- const rest = cliRef.slice(start);
28
- const nextH2 = rest.search(/\n## (?!Registries)/);
29
- return nextH2 === -1 ? rest : rest.slice(0, nextH2);
30
- }
31
- describe('operator-environments docs contract (RF-5.2)', () => {
32
- it('runbook team-registries leads with scaffold and mentions doctor + design RF-5.2 out-of-scope', () => {
33
- const runbook = fs_1.default.readFileSync(runbookPath, 'utf-8');
34
- const section = teamRegistriesSection(runbook);
35
- const scaffoldIdx = section.indexOf('awm registry scaffold');
36
- const addIdx = section.indexOf('awm registry add');
37
- expect(scaffoldIdx).toBeGreaterThanOrEqual(0);
38
- expect(addIdx).toBeGreaterThan(scaffoldIdx);
39
- expect(section).toContain('awm registry doctor');
40
- // RF-5.2: Cenco infra registry is out of scope — require the out-of-scope
41
- // phrase near the cenco mention (same paragraph/window), not a loose
42
- // match elsewhere in the section.
43
- expect(section).toMatch(/RF-5\.2/);
44
- expect(section).toContain(designPath);
45
- const cencoIdx = section.search(/awm-cenco-infra-registry/);
46
- expect(cencoIdx).toBeGreaterThanOrEqual(0);
47
- const windowStart = Math.max(0, cencoIdx - 120);
48
- const windowEnd = Math.min(section.length, cencoIdx + 160);
49
- const nearCenco = section.slice(windowStart, windowEnd);
50
- expect(nearCenco).toMatch(/out of scope|out-of-scope|does not modify|SHALL NOT modify/i);
51
- });
52
- it('cli-reference documents registry scaffold, registry doctor, and awm env', () => {
53
- const cliRef = fs_1.default.readFileSync(cliReferencePath, 'utf-8');
54
- const registries = registriesSection(cliRef);
55
- expect(registries).toMatch(/###\s+`awm registry scaffold/);
56
- expect(registries).toMatch(/###\s+`awm registry doctor/);
57
- // env lives as its own H2; require the three command strings in the file
58
- // with scoped checks so headings cannot be satisfied by a stray mention.
59
- expect(cliRef).toContain('awm registry scaffold');
60
- expect(cliRef).toContain('awm registry doctor');
61
- const envStart = cliRef.search(/^##\s+.*\benv\b/im);
62
- expect(envStart).toBeGreaterThanOrEqual(0);
63
- const envRest = cliRef.slice(envStart);
64
- const envNext = envRest.search(/\n## /);
65
- const envSection = envNext === -1 ? envRest : envRest.slice(0, envNext);
66
- expect(envSection).toMatch(/awm env/);
67
- expect(envSection).toMatch(/env set|`awm env set`/i);
68
- expect(envSection).toMatch(/env status|`awm env status`/i);
69
- });
70
- });
@@ -1,34 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const fs_1 = __importDefault(require("fs"));
7
- const path_1 = __importDefault(require("path"));
8
- const DESIGN = path_1.default.resolve(__dirname, '../../../docs/plans/2026-08-23-process-lifecycle-design.md');
9
- function artifactSection() {
10
- const text = fs_1.default.readFileSync(DESIGN, 'utf8');
11
- const start = text.indexOf('### El artefacto');
12
- expect(start).toBeGreaterThan(-1);
13
- const end = text.indexOf('\n### ', start + 1);
14
- return text.slice(start, end === -1 ? undefined : end);
15
- }
16
- describe('process-model contract documents the optional description (PD-4)', () => {
17
- it('lists description in the frontmatter block as optional', () => {
18
- const section = artifactSection();
19
- expect(section).toMatch(/^description: <texto de una línea> {2}# opcional$/m);
20
- });
21
- it('states the rules the parser enforces and why the field exists', () => {
22
- /** Whitespace-normalized so re-wrapping the prose never breaks a pinned phrase. */
23
- const section = artifactSection().replace(/\s+/g, ' ');
24
- expect(section).toContain('#### Enmienda 2026-10-18 — `description` opcional');
25
- expect(section).toContain('una sola línea');
26
- expect(section).toContain('1024 caracteres');
27
- expect(section).toContain('Codex');
28
- expect(section).toContain('único campo opcional');
29
- expect(section).toContain('parser YAML');
30
- expect(section).not.toContain('no reemplaza a un parser YAML');
31
- expect(section).toContain('code points');
32
- expect(section).toContain('caracteres de control');
33
- });
34
- });
@@ -1,104 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const fs_1 = __importDefault(require("fs"));
7
- const path_1 = __importDefault(require("path"));
8
- /**
9
- * CMD-DOCS — RF-5.1 / RF-5.2 (project-declared sensors documentation).
10
- *
11
- * Resolves awm-baseline-registry from (in order):
12
- * 1. `AWM_BASELINE_REGISTRY_ROOT` (CI docs checkout)
13
- * 2. nested `repoRoot/awm-baseline-registry` (CI support-matrix layout)
14
- * 3. sibling `repoRoot/../awm-baseline-registry` (maintainer workspace)
15
- *
16
- * Prefer a checkout that already contains RF-5.1 (`## Project sensors vs packs`).
17
- * Missing / too-old checkouts fail loudly (no silent skip).
18
- */
19
- const repoRoot = path_1.default.resolve(__dirname, '../../..');
20
- const cliReferencePath = path_1.default.join(repoRoot, 'docs', 'cli-reference.md');
21
- const RF51_HEADING = '## Project sensors vs packs';
22
- function setupSensorsSkillPath(registryRoot) {
23
- return path_1.default.join(registryRoot, 'skills', 'setup-sensors', 'SKILL.md');
24
- }
25
- function resolveSetupSensorsPath() {
26
- const envRoot = process.env.AWM_BASELINE_REGISTRY_ROOT?.trim();
27
- // When CI/maintainer sets the override, that root is authoritative (no silent
28
- // fallback to a nested immutable pin that lacks RF-5.1 prose).
29
- const candidates = envRoot
30
- ? [path_1.default.resolve(envRoot)]
31
- : [
32
- path_1.default.join(repoRoot, 'awm-baseline-registry'),
33
- path_1.default.join(repoRoot, '..', 'awm-baseline-registry'),
34
- ];
35
- const existing = candidates
36
- .map(root => ({ root, skill: setupSensorsSkillPath(root) }))
37
- .filter(entry => fs_1.default.existsSync(entry.skill));
38
- if (existing.length === 0) {
39
- throw new Error('Baseline registry checkout missing for RF-5.1 docs contract. Tried:\n'
40
- + candidates.map(root => ` - ${setupSensorsSkillPath(root)}`).join('\n')
41
- + '\nClone awm-baseline-registry as a sibling, nest it under the CLI repo, '
42
- + 'or set AWM_BASELINE_REGISTRY_ROOT to a checkout that includes setup-sensors RF-5.1.');
43
- }
44
- const withRf51 = existing.find(entry => fs_1.default.readFileSync(entry.skill, 'utf8').includes(RF51_HEADING));
45
- if (!withRf51) {
46
- throw new Error('Baseline registry checkout is present but too old for RF-5.1 '
47
- + `(missing ${RF51_HEADING}). Checked:\n`
48
- + existing.map(entry => ` - ${entry.skill}`).join('\n')
49
- + '\nPoint AWM_BASELINE_REGISTRY_ROOT at a registry tip that documents project-declared sensors '
50
- + '(coordinated awm-baseline-registry PR), without replacing the immutable v2.0.1 support-matrix pin.');
51
- }
52
- return withRf51.skill;
53
- }
54
- function sensorsSection(text) {
55
- const start = text.indexOf('## Sensors (per-project computational checks)');
56
- expect(start).toBeGreaterThanOrEqual(0);
57
- const rest = text.slice(start);
58
- const nextH2 = rest.search(/\n## (?!Sensors)/);
59
- return nextH2 === -1 ? rest : rest.slice(0, nextH2);
60
- }
61
- /** Skill body after YAML frontmatter (content after the closing `---`). */
62
- function skillBody(skill) {
63
- const match = skill.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n([\s\S]*)$/);
64
- if (!match) {
65
- throw new Error('setup-sensors SKILL.md missing YAML frontmatter delimiters');
66
- }
67
- return match[1];
68
- }
69
- /** Named H2 section inside the skill body; fails if the heading is absent. */
70
- function skillSection(body, heading) {
71
- const start = body.indexOf(heading);
72
- expect(start).toBeGreaterThanOrEqual(0);
73
- const rest = body.slice(start);
74
- const nextH2 = rest.search(/\n## /);
75
- return nextH2 === -1 ? rest : rest.slice(0, nextH2);
76
- }
77
- describe('project-declared sensors docs contract (CMD-DOCS)', () => {
78
- it('cli-reference sensors section documents project markers, provenance, exit-code, and non-gating (RF-5.2)', () => {
79
- const text = fs_1.default.readFileSync(cliReferencePath, 'utf8');
80
- const section = sensorsSection(text);
81
- expect(section).toMatch(/source:\s*"project"|source"\s*:\s*"project"/);
82
- expect(section).toContain('project-declared');
83
- expect(section).toContain('exit-code');
84
- expect(section).toMatch(/provenance[\s\S]{0,220}(?:does not|never)\s+(?:block|blocks)[\s\S]{0,100}(?:unattended|gates)/i);
85
- // Optional pack (omit or null) — RF-5.2 clause already in cli-reference prose.
86
- expect(section).toMatch(/[Pp]ack may be omitted or set\s+to\s+`?null`?[\s\S]{0,120}project-declared/i);
87
- // JSON-vs-schema diagnostics distinction — RF-5.2.
88
- expect(section).toMatch(/not valid JSON[\s\S]{0,220}schema-invalid/i);
89
- });
90
- it('setup-sensors skill documents project vs pack, JSON example, and non-gating provenance (RF-5.1)', () => {
91
- const setupSensorsPath = resolveSetupSensorsPath();
92
- const skill = fs_1.default.readFileSync(setupSensorsPath, 'utf8');
93
- const body = skillBody(skill);
94
- // Scope when-to-use / project-vs-packs (and related RF-5.1 prose) to the
95
- // dedicated body section — frontmatter description must not satisfy these.
96
- const projectVsPacks = skillSection(body, RF51_HEADING);
97
- // Both guidance clauses are required — Prefer|Declare OR let either alone satisfy.
98
- expect(projectVsPacks).toMatch(/Prefer a \*\*pack\*\*/);
99
- expect(projectVsPacks).toMatch(/Declare a \*\*project sensor\*\*\s+when\s+the check is project-owned/i);
100
- expect(projectVsPacks).toMatch(/"source"\s*:\s*"project"/);
101
- expect(projectVsPacks).toMatch(/```json[\s\S]*?"source"\s*:\s*"project"[\s\S]*?```/);
102
- expect(projectVsPacks).toMatch(/project-declared[\s\S]{0,220}(?:does not|never)\s+(?:block|blocks)[\s\S]{0,100}unattended/i);
103
- });
104
- });
@@ -1,37 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const fs_1 = __importDefault(require("fs"));
7
- const path_1 = __importDefault(require("path"));
8
- const cliReference = fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../../docs/cli-reference.md'), 'utf8');
9
- const readme = fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../../README.md'), 'utf8');
10
- const installation = fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../../docs/installation.md'), 'utf8');
11
- const developmentProcess = fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../../docs/guides/development-process.md'), 'utf8');
12
- describe('R4 plan/currentness documentation contract', () => {
13
- it('documents plan validation and the unchanged legacy path', () => {
14
- expect(cliReference).toContain('awm plan validate PLAN_PATH');
15
- expect(cliReference).toMatch(/legacy/i);
16
- });
17
- it('documents strict currentness separately from minCliVersion compatibility', () => {
18
- expect(cliReference).toContain('--require-current');
19
- expect(cliReference).toContain('minCliVersion');
20
- expect(cliReference).toMatch(/currentness[\s\S]{0,700}compatib|compatib[\s\S]{0,700}currentness/i);
21
- });
22
- it('documents the exact cache-resistant bootstrap and its enforceable boundary', () => {
23
- expect(cliReference).toContain('npm exec --yes --package=agentic-workflow-manager@latest -- awm preflight --require-current');
24
- expect(cliReference).toMatch(/fresh CLI\/bootstrap/i);
25
- expect(cliReference).toMatch(/cannot update a host or cached container that\s+never runs new code/i);
26
- });
27
- it('keeps supported commands, remedies, bootstrap, and the enforceable boundary discoverable across user docs', () => {
28
- expect(readme).toContain('awm plan validate PLAN_PATH');
29
- expect(readme).toContain('awm preflight --require-current');
30
- expect(installation).toContain('npm exec --yes --package=agentic-workflow-manager@latest -- awm preflight --require-current');
31
- expect(installation).toMatch(/cannot update a host or cached container that\s+never runs new code/i);
32
- expect(developmentProcess).toContain('awm preflight --require-current');
33
- expect(developmentProcess).toContain('awm plan validate PLAN_PATH');
34
- expect(developmentProcess).toMatch(/awm update --yes/);
35
- expect(cliReference).toMatch(/awm unpin REGISTRY_NAME.*awm update --yes/s);
36
- });
37
- });
@@ -1,102 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const fs_1 = __importDefault(require("fs"));
7
- const path_1 = __importDefault(require("path"));
8
- /**
9
- * CMD-CLI-DOCS — RF-3.3 sensor execution optimization CLI reference.
10
- *
11
- * Section-scoped asserts only: a whole-file keyword must not satisfy these.
12
- * No registry file reads (CLI plan S5).
13
- */
14
- const repoRoot = path_1.default.resolve(__dirname, '../../..');
15
- const cliReferencePath = path_1.default.join(repoRoot, 'docs', 'cli-reference.md');
16
- function readCliReference() {
17
- return fs_1.default.readFileSync(cliReferencePath, 'utf8');
18
- }
19
- /** H2 Sensors block through the next H2. */
20
- function sensorsSection(text) {
21
- const start = text.indexOf('## Sensors (per-project computational checks)');
22
- expect(start).toBeGreaterThanOrEqual(0);
23
- const rest = text.slice(start);
24
- const nextH2 = rest.search(/\n## (?!Sensors)/);
25
- return nextH2 === -1 ? rest : rest.slice(0, nextH2);
26
- }
27
- /** Named H3 inside a parent section; fails if the heading is absent. */
28
- function h3Section(parent, heading) {
29
- const start = parent.indexOf(heading);
30
- expect(start).toBeGreaterThanOrEqual(0);
31
- const rest = parent.slice(start);
32
- const next = rest.search(/\n### /);
33
- return next === -1 ? rest : rest.slice(0, next);
34
- }
35
- /** Named H4 inside a parent section; fails if the heading is absent. */
36
- function h4Section(parent, heading) {
37
- const start = parent.indexOf(heading);
38
- expect(start).toBeGreaterThanOrEqual(0);
39
- const rest = parent.slice(start);
40
- const next = rest.search(/\n#### /);
41
- return next === -1 ? rest : rest.slice(0, next);
42
- }
43
- describe('sensor execution optimization docs contract (CMD-CLI-DOCS / RF-3.3)', () => {
44
- it('documents authored inputs and sensor-level closureOnly under Sensors', () => {
45
- const sensors = sensorsSection(readCliReference());
46
- const section = h3Section(sensors, '### Inputs and closureOnly');
47
- expect(section).toMatch(/`inputs`/);
48
- expect(section).toMatch(/variant|project override|pack/i);
49
- expect(section).toMatch(/no effective `inputs`[\s\S]{0,160}always execute|always execute[\s\S]{0,160}no effective `inputs`/i);
50
- expect(section).toMatch(/`closureOnly`/);
51
- expect(section).toMatch(/sensor-level|sensor object/i);
52
- expect(section).toMatch(/mutation[\s\S]{0,120}closureOnly|closureOnly[\s\S]{0,120}mutation/i);
53
- });
54
- it('documents --slice and --no-cache on awm sensors run', () => {
55
- const sensors = sensorsSection(readCliReference());
56
- const run = h3Section(sensors, '### `awm sensors run`');
57
- expect(run).toMatch(/--slice/);
58
- expect(run).toMatch(/closureOnly/);
59
- expect(run).toMatch(/--slice[\s\S]{0,200}(?:reject|refuse|not combine|cannot(?:\s+be)?\s+combin)[\s\S]{0,80}--(?:all|slow)|(?:--all|--slow)[\s\S]{0,120}(?:reject|refuse|not combine|cannot(?:\s+be)?\s+combin)[\s\S]{0,80}--slice/i);
60
- expect(run).toMatch(/--no-cache/);
61
- expect(run).toMatch(/isFullSelection|full[- ]gate|Change Record receipt/i);
62
- expect(run).toMatch(/--slice[\s\S]{0,200}(?:not|never|no)[\s\S]{0,80}receipt|receipt[\s\S]{0,120}--slice/i);
63
- });
64
- it('documents cache hit semantics, provenance, fingerprint, and failureKind', () => {
65
- const sensors = sensorsSection(readCliReference());
66
- const cache = h4Section(h3Section(sensors, '### `awm sensors run`'), '#### Result cache');
67
- expect(cache).toMatch(/cache hit|cached:\s*`?true`?/i);
68
- expect(cache).toMatch(/originDirty/);
69
- expect(cache).toMatch(/fingerprint|sensorFingerprint/i);
70
- expect(cache).toMatch(/always-measured|alwaysMeasured/i);
71
- expect(cache).toMatch(/live[\s\S]{0,80}version|liveState/i);
72
- expect(cache).toMatch(/failureKind/);
73
- expect(cache).toMatch(/findings/);
74
- expect(cache).toMatch(/missing-binary|exit-code/);
75
- expect(cache).toMatch(/\.awm\/sensors\/runs\//);
76
- expect(cache).toMatch(/pre-baseline|before baseline|raw[\s\S]{0,40}baseline/i);
77
- expect(cache).toMatch(/--changed[\s\S]{0,160}(?:not|never|must not)[\s\S]{0,80}(?:write|cache)|(?:write|cache)[\s\S]{0,120}(?:not|never)[\s\S]{0,80}--changed/i);
78
- });
79
- it('documents receipt schema 2 and RF-4.6 Change Record honesty', () => {
80
- const sensors = sensorsSection(readCliReference());
81
- const receipt = h4Section(h3Section(sensors, '### `awm sensors run`'), '#### Sensor receipt');
82
- expect(receipt).toMatch(/"schema"\s*:\s*2|schema\s*`?2`?/);
83
- expect(receipt).toMatch(/measurements/);
84
- expect(receipt).toMatch(/alwaysMeasuredPaths|always-measured/i);
85
- // RF-4.6 honesty only — "legacy late-path rules" elsewhere must not satisfy this.
86
- expect(receipt).toMatch(/RF-4\.6[\s\S]{0,80}honesty[\s\S]{0,400}schema-1 late-path|schema-1 late-path[\s\S]{0,400}RF-4\.6[\s\S]{0,80}honesty/i);
87
- expect(receipt).toMatch(/(?:any|every)[\s\S]{0,80}(?:without|no|lacks)[\s\S]{0,60}inputs[\s\S]{0,160}schema[\s\S]{0,40}1|schema[\s\S]{0,40}1[\s\S]{0,160}(?:without|no|lacks)[\s\S]{0,60}inputs/i);
88
- expect(receipt).toMatch(/docs-only|documentation-only|docs only/i);
89
- expect(receipt).toMatch(/project override/i);
90
- });
91
- it('documents RF-4.7 change new remedy honesty (full-gate + cache reuse)', () => {
92
- const text = readCliReference();
93
- const start = text.indexOf('### `awm change new <slug>`');
94
- expect(start).toBeGreaterThanOrEqual(0);
95
- const rest = text.slice(start);
96
- const nextH3 = rest.search(/\n### /);
97
- const section = nextH3 === -1 ? rest : rest.slice(0, nextH3);
98
- // Must match REMEDY_RECEIPT honesty — not a bare `awm sensors run` that implies every binary re-execs.
99
- expect(section).toMatch(/receipt-missing[\s\S]{0,200}full-gate[\s\S]{0,80}awm sensors run[\s\S]{0,120}cache may reuse/i);
100
- expect(section.toLowerCase()).not.toMatch(/every tool|must re-exec|reexecute every/);
101
- });
102
- });