@outerlayer/cli 0.34.0-next.20261026182624 → 0.34.0-next.20261026200155

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 (114) hide show
  1. package/dist/{agent-setup-WOEZELVB.js → agent-setup-2A6P2SYL.js} +10 -10
  2. package/dist/{artifact-link-cmd-LWPY3V4N.js → artifact-link-cmd-4XQJO55P.js} +2 -2
  3. package/dist/{build-UDOBVX5J.js → build-BBWAD5LR.js} +4 -4
  4. package/dist/{build-disk-C3WIAHCL.js → build-disk-TGLM5XK7.js} +4 -4
  5. package/dist/build-info.json +1 -1
  6. package/dist/{builder-YNXWVH2V.js → builder-FD53GTWL.js} +3 -3
  7. package/dist/{check-G2K76NEM.js → check-FOWN6M3C.js} +34 -34
  8. package/dist/{chunk-GHFI5GBF.js → chunk-25XBOX3K.js} +3 -3
  9. package/dist/{chunk-VEJWLQ4G.js → chunk-2GDKM2O4.js} +12 -12
  10. package/dist/{chunk-IWVGALDC.js → chunk-3HJMY3H5.js} +1 -1
  11. package/dist/{chunk-V2VJYK46.js → chunk-3NCWHEGM.js} +2 -2
  12. package/dist/{chunk-CNZRUVZ5.js → chunk-3PUOHONX.js} +11 -11
  13. package/dist/{chunk-P3CHDKXD.js → chunk-5ZBVKRDK.js} +2 -2
  14. package/dist/{chunk-5JGPTYLT.js → chunk-66LH5QAV.js} +3 -3
  15. package/dist/{chunk-6D7H5DMZ.js → chunk-6CK2OC4Q.js} +2 -2
  16. package/dist/{chunk-7FQYTM7M.js → chunk-72CJOYN6.js} +7 -7
  17. package/dist/{chunk-EPFFYDNX.js → chunk-77VBS2RT.js} +2 -2
  18. package/dist/{chunk-XSFR76J7.js → chunk-7DK2FOZ4.js} +4 -4
  19. package/dist/{chunk-ZIKZZ4LK.js → chunk-BQQPDBSF.js} +2 -2
  20. package/dist/{chunk-NHEU5CON.js → chunk-CCHSD7RS.js} +2 -2
  21. package/dist/{chunk-EOTMDIYC.js → chunk-DINRXUQA.js} +43 -2
  22. package/dist/{chunk-JSZRBQY3.js → chunk-EBVK3QBO.js} +3 -3
  23. package/dist/{chunk-LTN2YFLR.js → chunk-FVF2LMVG.js} +12 -12
  24. package/dist/{chunk-MECW77XP.js → chunk-IXPH4EXK.js} +1 -1
  25. package/dist/{chunk-4P6QGMPN.js → chunk-J7EJMIDR.js} +2 -2
  26. package/dist/{chunk-LTYBHCL4.js → chunk-JA2ARVY6.js} +6 -6
  27. package/dist/{chunk-SZU4YCBH.js → chunk-JKLSQOYO.js} +16 -16
  28. package/dist/{chunk-ELO5XEES.js → chunk-K3ACC2CV.js} +475 -103
  29. package/dist/{chunk-GYVMMU3U.js → chunk-KR2TIRNQ.js} +7 -7
  30. package/dist/{chunk-RCRE42V6.js → chunk-LASKTDCR.js} +1 -1
  31. package/dist/{chunk-JWNH4ZTF.js → chunk-LMYRR5MO.js} +2 -2
  32. package/dist/{chunk-WE4C3ODP.js → chunk-LY62UHRR.js} +1 -1
  33. package/dist/{chunk-NKOM4JKY.js → chunk-LYCJQOO2.js} +2 -2
  34. package/dist/{chunk-4J2FF5HZ.js → chunk-MYLOOVRJ.js} +3 -3
  35. package/dist/{chunk-Y5YCX6AL.js → chunk-NWHU5G6R.js} +1 -1
  36. package/dist/{chunk-EUQZAH2W.js → chunk-O7QPHJWN.js} +4 -4
  37. package/dist/{chunk-IO2BBKG4.js → chunk-OKGHWCSK.js} +2 -2
  38. package/dist/{chunk-Z7WMU3RA.js → chunk-OOD5NDQA.js} +1 -1
  39. package/dist/{chunk-ZQSANKS4.js → chunk-OVNF4LLC.js} +1 -1
  40. package/dist/{chunk-JKNOJKVD.js → chunk-QABXXQ67.js} +5 -5
  41. package/dist/{chunk-VUQKGBIQ.js → chunk-QRJIBTNQ.js} +5 -5
  42. package/dist/{chunk-XL2MPORM.js → chunk-QWXBWOVV.js} +5 -5
  43. package/dist/{chunk-ERTIEYDG.js → chunk-RNMCFAYH.js} +3 -3
  44. package/dist/{chunk-HVPW272H.js → chunk-T2HH7IHT.js} +1 -1
  45. package/dist/{chunk-KPHRRCUY.js → chunk-TWFBOZQ5.js} +4 -4
  46. package/dist/{chunk-XKJOIQ2Q.js → chunk-TZMDRHWB.js} +4 -4
  47. package/dist/{chunk-DQ6YO7FH.js → chunk-UPA5KOOX.js} +1 -1
  48. package/dist/{chunk-LD3BHLK7.js → chunk-WBTPI5MP.js} +3 -3
  49. package/dist/{chunk-OQT7RT5I.js → chunk-WYR4INK3.js} +2 -2
  50. package/dist/{chunk-FGXT5OXS.js → chunk-XFJ7YOPD.js} +1 -1
  51. package/dist/{chunk-H47VGSCW.js → chunk-XHZBLIB2.js} +1 -1
  52. package/dist/{chunk-HVQMIZ22.js → chunk-XYLHSCLR.js} +1 -1
  53. package/dist/{chunk-JC6AQ6PC.js → chunk-ZADRW2V2.js} +4 -4
  54. package/dist/{claude-launcher-6KGANL7E.js → claude-launcher-EO3ALKBS.js} +5 -5
  55. package/dist/{cli-5KY3TE3S.js → cli-3RDQSLYI.js} +115 -110
  56. package/dist/{command-VQPQDPCZ.js → command-C5YKBTK4.js} +20 -20
  57. package/dist/{config-WSZIWPP4.js → config-EBT5VYPX.js} +5 -5
  58. package/dist/{connect-cmd-LI34HS5Q.js → connect-cmd-65YBQRSY.js} +8 -8
  59. package/dist/{container-start-XRR4VC5Z.js → container-start-RLX2PL3C.js} +31 -31
  60. package/dist/{context-cleanup-LUBEZB3L.js → context-cleanup-VJXMM27E.js} +3 -3
  61. package/dist/{context-show-cmd-X27GMOT6.js → context-show-cmd-S5SEBOI2.js} +9 -9
  62. package/dist/{control-plane-launch-74EIIB5Z.js → control-plane-launch-BDSUP4DK.js} +6 -6
  63. package/dist/demo-voice-cmd-DF6C7EST.js +83 -0
  64. package/dist/{dist-HVXLUMRV.js → dist-ADKRGE7I.js} +2 -2
  65. package/dist/{docker-KZ3OQTPW.js → docker-CP656XNO.js} +3 -3
  66. package/dist/{doctor-KPKLFIJH.js → doctor-EQIAHHZD.js} +21 -21
  67. package/dist/{emit-artifact-cmd-BJICHW2E.js → emit-artifact-cmd-56C6DBUP.js} +13 -13
  68. package/dist/{emit-cmd-7TU3JBJ2.js → emit-cmd-C3BUFAUR.js} +6 -6
  69. package/dist/{emit-criteria-cmd-MUWPT25P.js → emit-criteria-cmd-HRCWXD3W.js} +10 -10
  70. package/dist/{emit-demo-cmd-YQN7VKQH.js → emit-demo-cmd-YKTL6XWP.js} +15 -14
  71. package/dist/{emit-finding-cmd-NPBWVY44.js → emit-finding-cmd-6MVFN4BO.js} +10 -10
  72. package/dist/{emit-result-cmd-7CJZZQGK.js → emit-result-cmd-E3YYBXRY.js} +12 -12
  73. package/dist/{emit-step-cmd-ZPLHZAMA.js → emit-step-cmd-DM4CRYYI.js} +10 -10
  74. package/dist/{find-unit-UKH6JH4S.js → find-unit-O6WL6UIW.js} +7 -7
  75. package/dist/{findings-cmd-DZ4ESTHX.js → findings-cmd-K2OYBTUH.js} +10 -10
  76. package/dist/{fleet-readiness-YSI4NOHT.js → fleet-readiness-VIAVQYRP.js} +8 -8
  77. package/dist/{governing-source-JPRMOB3O.js → governing-source-MQA2SDJT.js} +13 -13
  78. package/dist/{hook-fast-6EW2MGA2.js → hook-fast-KXAQ22LZ.js} +1 -1
  79. package/dist/{host-checks-NDXNYOMA.js → host-checks-V25YUP4Q.js} +29 -29
  80. package/dist/index.js +4 -4
  81. package/dist/{init-V6Y2VNKW.js → init-KO3FT2XP.js} +20 -20
  82. package/dist/{init-MN3MNG7V.js → init-YYZ7B4ZD.js} +20 -20
  83. package/dist/{init-cmd-QCWLJDIF.js → init-cmd-D3BDS7KY.js} +18 -18
  84. package/dist/{init-update-GTFLPDEL.js → init-update-JMVLGBDE.js} +17 -17
  85. package/dist/{layout-7B3O3FT3.js → layout-KRWLUGYZ.js} +4 -4
  86. package/dist/{login-browser-DQ6YRXUB.js → login-browser-BAFZYJBR.js} +2 -2
  87. package/dist/{loop-NGFNQF3Y.js → loop-UVONXWXB.js} +33 -33
  88. package/dist/{machine-XG54XYYZ.js → machine-2BI76JZO.js} +20 -20
  89. package/dist/{machine-skills-3FEGR376.js → machine-skills-YVS4ZYCT.js} +4 -4
  90. package/dist/{runner-env-YPXWTNP3.js → runner-env-QN4BLTVZ.js} +7 -7
  91. package/dist/{runner-identity-XPZO3TG4.js → runner-identity-53I4UTVY.js} +3 -3
  92. package/dist/{runner-key-B5EJH25Z.js → runner-key-JKXJWGGY.js} +20 -20
  93. package/dist/{session-sender-XED7CKHP.js → session-sender-KLOMLL7X.js} +13 -13
  94. package/dist/{spec-cmd-TRXAGQYM.js → spec-cmd-MX5QFW32.js} +11 -11
  95. package/dist/{starter-pack-LEL3Q2DB.js → starter-pack-QWDE6FDK.js} +5 -5
  96. package/dist/{status-WQ53MWC3.js → status-YCQHAY45.js} +29 -29
  97. package/dist/{sync-cmd-UQVENF25.js → sync-cmd-CO4DFMHU.js} +12 -12
  98. package/dist/{update-steps-IQVAL64Y.js → update-steps-MC3IUHW7.js} +30 -30
  99. package/dist/{watch-EZGDDRTQ.js → watch-GU62YVQY.js} +12 -12
  100. package/dist/{work-claim-cmd-YSAJ7DAK.js → work-claim-cmd-O54L5DSL.js} +15 -15
  101. package/dist/{work-cmd-V5FHLWJM.js → work-cmd-VR7PPSP6.js} +10 -10
  102. package/dist/{work-comment-cmd-KLEMDYI4.js → work-comment-cmd-HVZF72B4.js} +11 -11
  103. package/dist/{work-demo-cmd-XYRKFP4G.js → work-demo-cmd-EDGNM5VJ.js} +10 -10
  104. package/dist/{work-logs-cmd-DOGPK7Q6.js → work-logs-cmd-ZZVAHX36.js} +10 -10
  105. package/dist/{work-open-pr-cmd-UAUEEP3V.js → work-open-pr-cmd-AQWZRJHZ.js} +11 -11
  106. package/dist/{work-pr-cmd-LYWL7ZLF.js → work-pr-cmd-UJ7VWCJN.js} +10 -10
  107. package/dist/{work-proofs-cmd-YMMDAA6W.js → work-proofs-cmd-LIXV252G.js} +12 -12
  108. package/dist/{work-proofs-record-NUCWR7ZJ.js → work-proofs-record-MCSA56F5.js} +19 -18
  109. package/dist/{work-stop-cmd-MRLJEQRP.js → work-stop-cmd-SAT4XVM2.js} +10 -10
  110. package/package.json +1 -1
  111. package/skill-pack/maintained/outerlayer-build/references/agent-briefs.md +17 -3
  112. package/skill-pack/maintained/outerlayer-build/references/evidence.md +6 -1
  113. package/skill-pack/maintained/outerlayer-evidence/SKILL.md +19 -40
  114. package/skill-pack/maintained/outerlayer-evidence/references/demo.md +75 -0
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { classifyProofs, classifyProofsAt, otherPullRequestHeads, resolveProofsItem, runWorkProofs, runWorkProofsCommand } from './chunk-GYVMMU3U.js';
4
- import './chunk-6D7H5DMZ.js';
5
- import './chunk-JKNOJKVD.js';
3
+ export { classifyProofs, classifyProofsAt, otherPullRequestHeads, resolveProofsItem, runWorkProofs, runWorkProofsCommand } from './chunk-KR2TIRNQ.js';
4
+ import './chunk-6CK2OC4Q.js';
5
+ import './chunk-QABXXQ67.js';
6
6
  import './chunk-IP7BIBXJ.js';
7
- import './chunk-IO2BBKG4.js';
8
- import './chunk-EUQZAH2W.js';
9
- import './chunk-Y5YCX6AL.js';
7
+ import './chunk-OKGHWCSK.js';
8
+ import './chunk-O7QPHJWN.js';
9
+ import './chunk-NWHU5G6R.js';
10
10
  import './chunk-G2JWZDFA.js';
11
11
  import './chunk-ANPNT6PM.js';
12
- import './chunk-MECW77XP.js';
13
- import './chunk-NKOM4JKY.js';
12
+ import './chunk-IXPH4EXK.js';
13
+ import './chunk-LYCJQOO2.js';
14
14
  import './chunk-7QAJQDHS.js';
15
15
  import './chunk-PJDQPF5N.js';
16
16
  import './chunk-L5VHGRQE.js';
17
17
  import './chunk-BJ3KTMDH.js';
18
- import './chunk-ZQSANKS4.js';
19
- import './chunk-Z7WMU3RA.js';
18
+ import './chunk-OVNF4LLC.js';
19
+ import './chunk-OOD5NDQA.js';
20
20
  import './chunk-5BHIBJDA.js';
21
21
  import './chunk-CDDED64E.js';
22
22
  import './chunk-RA3O54FC.js';
@@ -24,8 +24,8 @@ import './chunk-T2Q7ISPE.js';
24
24
  import './chunk-WZBHBH3J.js';
25
25
  import './chunk-CRB3POP4.js';
26
26
  import './chunk-YQR6E6OV.js';
27
- import './chunk-FGXT5OXS.js';
28
- import './chunk-EOTMDIYC.js';
27
+ import './chunk-XFJ7YOPD.js';
28
+ import './chunk-DINRXUQA.js';
29
29
  import './chunk-VNVZDWO3.js';
30
30
  import './chunk-GJ4KBHBD.js';
31
31
  import './chunk-SDAEXUIX.js';
@@ -1,37 +1,38 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { runWorkComment } from './chunk-JSZRBQY3.js';
4
- import { resolveProofsItem, ownPullRequest, proofsCommentId, otherPullRequestHeads, classifyProofsAt, kindProblem, proofsCommentBody, runWorkProofs } from './chunk-GYVMMU3U.js';
5
- import './chunk-6D7H5DMZ.js';
6
- import { runEmitDemo } from './chunk-ELO5XEES.js';
3
+ import { resolveProofsItem, ownPullRequest, proofsCommentId, otherPullRequestHeads, classifyProofsAt, kindProblem, proofsCommentBody, runWorkProofs } from './chunk-KR2TIRNQ.js';
4
+ import { runWorkComment } from './chunk-EBVK3QBO.js';
5
+ import './chunk-6CK2OC4Q.js';
6
+ import { runEmitDemo } from './chunk-K3ACC2CV.js';
7
7
  import { readNewestDemo } from './chunk-ER6KQCVJ.js';
8
- import { runEmitArtifact } from './chunk-XL2MPORM.js';
9
- import { runSync } from './chunk-VUQKGBIQ.js';
10
- import './chunk-XSFR76J7.js';
8
+ import { runEmitArtifact } from './chunk-QWXBWOVV.js';
9
+ import { runSync } from './chunk-QRJIBTNQ.js';
10
+ import './chunk-7DK2FOZ4.js';
11
11
  import './chunk-ESVW4MJY.js';
12
12
  import './chunk-TBT347UY.js';
13
13
  import './chunk-2PGI6RDE.js';
14
+ import './chunk-TQMI335S.js';
14
15
  import './chunk-4UPET3R7.js';
15
- import { WorkCommandError, resolveCredentials, getJson } from './chunk-JKNOJKVD.js';
16
+ import { WorkCommandError, resolveCredentials, getJson } from './chunk-QABXXQ67.js';
16
17
  import './chunk-IP7BIBXJ.js';
17
- import './chunk-IO2BBKG4.js';
18
- import './chunk-EUQZAH2W.js';
19
- import './chunk-Y5YCX6AL.js';
18
+ import './chunk-OKGHWCSK.js';
19
+ import './chunk-O7QPHJWN.js';
20
+ import './chunk-NWHU5G6R.js';
20
21
  import './chunk-G2JWZDFA.js';
21
22
  import './chunk-ANPNT6PM.js';
22
- import './chunk-MECW77XP.js';
23
- import './chunk-NKOM4JKY.js';
23
+ import './chunk-IXPH4EXK.js';
24
+ import './chunk-LYCJQOO2.js';
24
25
  import { defaultFetch } from './chunk-7QAJQDHS.js';
25
26
  import './chunk-PJDQPF5N.js';
26
27
  import './chunk-L5VHGRQE.js';
27
- import './chunk-NHEU5CON.js';
28
+ import './chunk-CCHSD7RS.js';
28
29
  import './chunk-ZJSNLVCE.js';
29
30
  import './chunk-2O5KA67H.js';
30
31
  import './chunk-BKO6JEZI.js';
31
32
  import './chunk-HCVLP7XA.js';
32
33
  import './chunk-BJ3KTMDH.js';
33
- import './chunk-ZQSANKS4.js';
34
- import { resolveRepoIdentity } from './chunk-Z7WMU3RA.js';
34
+ import './chunk-OVNF4LLC.js';
35
+ import { resolveRepoIdentity } from './chunk-OOD5NDQA.js';
35
36
  import './chunk-5BHIBJDA.js';
36
37
  import './chunk-CDDED64E.js';
37
38
  import './chunk-RA3O54FC.js';
@@ -41,8 +42,8 @@ import './chunk-CRB3POP4.js';
41
42
  import './chunk-URIZRCRY.js';
42
43
  import './chunk-YQR6E6OV.js';
43
44
  import './chunk-TUSYOL2O.js';
44
- import { parseProofsConfig } from './chunk-FGXT5OXS.js';
45
- import { ARTIFACT_MAX_CAPTION_LENGTH } from './chunk-EOTMDIYC.js';
45
+ import { parseProofsConfig } from './chunk-XFJ7YOPD.js';
46
+ import { ARTIFACT_MAX_CAPTION_LENGTH } from './chunk-DINRXUQA.js';
46
47
  import './chunk-VNVZDWO3.js';
47
48
  import './chunk-GJ4KBHBD.js';
48
49
  import './chunk-SDAEXUIX.js';
@@ -1,27 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { resolveCredentials, postJson, WorkCommandError } from './chunk-JKNOJKVD.js';
3
+ import { resolveCredentials, postJson, WorkCommandError } from './chunk-QABXXQ67.js';
4
4
  import './chunk-IP7BIBXJ.js';
5
- import './chunk-IO2BBKG4.js';
6
- import './chunk-EUQZAH2W.js';
7
- import './chunk-Y5YCX6AL.js';
5
+ import './chunk-OKGHWCSK.js';
6
+ import './chunk-O7QPHJWN.js';
7
+ import './chunk-NWHU5G6R.js';
8
8
  import './chunk-G2JWZDFA.js';
9
9
  import './chunk-ANPNT6PM.js';
10
- import './chunk-MECW77XP.js';
11
- import './chunk-NKOM4JKY.js';
10
+ import './chunk-IXPH4EXK.js';
11
+ import './chunk-LYCJQOO2.js';
12
12
  import { defaultFetch } from './chunk-7QAJQDHS.js';
13
13
  import './chunk-PJDQPF5N.js';
14
14
  import './chunk-L5VHGRQE.js';
15
15
  import './chunk-BJ3KTMDH.js';
16
- import './chunk-ZQSANKS4.js';
17
- import './chunk-Z7WMU3RA.js';
16
+ import './chunk-OVNF4LLC.js';
17
+ import './chunk-OOD5NDQA.js';
18
18
  import './chunk-5BHIBJDA.js';
19
19
  import './chunk-CDDED64E.js';
20
20
  import './chunk-RA3O54FC.js';
21
21
  import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
22
22
  import './chunk-CRB3POP4.js';
23
- import './chunk-FGXT5OXS.js';
24
- import './chunk-EOTMDIYC.js';
23
+ import './chunk-XFJ7YOPD.js';
24
+ import './chunk-DINRXUQA.js';
25
25
  import './chunk-VNVZDWO3.js';
26
26
  import './chunk-GJ4KBHBD.js';
27
27
  import './chunk-SDAEXUIX.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outerlayer/cli",
3
- "version": "0.34.0-next.20261026182624",
3
+ "version": "0.34.0-next.20261026200155",
4
4
  "description": "OuterLayer CLI — commands: init, claude, connect, doctor, login, logout, sync, daemon (alias: watch), emit, findings, work, spec, runner, hooks, mcp, context. Capture and sync coding-agent sessions, and record proof of factory work.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Magu Studios, Inc.",
@@ -277,12 +277,26 @@ tests at HEAD that hold the id of each proof that is not current, and runs them.
277
277
  files go.
278
278
  - A demo test uses `@outerlayer/playwright`, one chapter for each screenshot or
279
279
  video criterion in the criteria's order, as the outerlayer-evidence skill's
280
- "Record a demo" says. The fixture writes the manifest where
281
- `OUTERLAYER_PROOF_OUT` names.
280
+ "Record a demo" says. Tell each chapter in beats with `demo.say()`: sign in
281
+ once, and seed and wait between beats, so the demo shows only narrated
282
+ steps. Render it with `outerlayer emit demo <manifest> --output demo.webm`
283
+ and watch it before you commit the test. The fixture writes the manifest
284
+ where `OUTERLAYER_PROOF_OUT` names.
282
285
  - A report, log or file proof is a test, in any language, that writes
283
286
  `$OUTERLAYER_PROOF_OUT/<criterion id>.<ext>`. The kind of the file must be the
284
287
  kind the criterion declares. The test writes outside the repository, so there is
285
288
  nothing to ignore or commit.
289
+ - A `test` proof is a JUnit XML file of test results, bound to the criterion.
290
+ `--record` does not record it, so record it yourself, unless the policy file
291
+ sets `criteria.test_proof: ci`. CI then records it. Run the repository's test
292
+ command with its JUnit reporter, such as
293
+ `vitest run --reporter=junit --outputFile=<file>`, `pytest --junitxml=<file>`
294
+ or `node --test --test-reporter=junit --test-reporter-destination=<file>`.
295
+ Write the file outside the repository. Then run
296
+ `outerlayer emit artifact <file> --caption "<one sentence>" --for <criterion id>`.
297
+ Add `--test "<test name>"` for each test that cites the criterion, unless the
298
+ criterion is about the whole suite. To replace an earlier result, add
299
+ `--replaces <its id>`.
286
300
  - A proof that no test can make stays without a test. Give the reason in
287
301
  `build-reports/evidence.md`.
288
302
 
@@ -290,7 +304,7 @@ Commit the setup file and every test. Then run
290
304
  `outerlayer work proofs --record` from the committed checkout. It stops when a
291
305
  tracked file differs from HEAD. It runs only what is committed at HEAD, and
292
306
  emits each proof at HEAD. It skips a proof that is current. Never emit by hand
293
- a proof that a test can make. Always pass `--pr <number>` when the item links
307
+ a proof that a test can make, except a `test` proof, as above. Always pass `--pr <number>` when the item links
294
308
  more than one pull request in the repository.
295
309
 
296
310
  The output names each proof that is still not current, with the reason. Fix
@@ -10,7 +10,7 @@ earlier phase from the state file.
10
10
  ## The phase
11
11
 
12
12
  The orchestrator does not run the app, drive a browser or emit an artifact
13
- itself. Spawn one evidence agent in a fresh context on the Evidence brief, with
13
+ itself. The one exception is the test results it records at the last head. Spawn one evidence agent in a fresh context on the Evidence brief, with
14
14
  the issue, the pull request number, the criteria that declare a proof form, the
15
15
  instructions-file pointer and the outerlayer-evidence skill.
16
16
 
@@ -45,6 +45,11 @@ proof that is not current and skips the rest. If a commit lands after that,
45
45
  record once more after it. The final report names that head and the proofs
46
46
  recorded there.
47
47
 
48
+ `--record` skips a criterion that declares `proof: test`, and the list command
49
+ leaves it out. So at that same head, record each one as the Evidence brief in
50
+ [agent-briefs.md](agent-briefs.md) says, unless the policy file sets
51
+ `criteria.test_proof: ci`. The final report names each one with its artifact.
52
+
48
53
  Run the list command once more before the run ends. A criterion still listed
49
54
  as out of date or missing goes in `build-reports/evidence.md` with the reason.
50
55
  A written reason never excuses an `uncited` or `failed` row. Fix it first. Never
@@ -78,51 +78,30 @@ the recorded list does not hold gets no row.
78
78
 
79
79
  ## Record a demo
80
80
 
81
- Record every video proof as a chapter of the item's one demo. A demo has
82
- one chapter for each criterion that declares a video, in the criteria's
83
- order. Each chapter is that criterion's video proof, with a spoken line and the
84
- checks that ran. Emit a video with `emit artifact` only when Playwright cannot
85
- drive the flow.
81
+ Record every video proof, and every `proof: screenshot` criterion a test can
82
+ reach, as a chapter of the item's one demo. Emit a video with `emit artifact`
83
+ only when Playwright cannot drive the flow.
86
84
 
87
- Write a Playwright test with `@outerlayer/playwright`, one `demo.chapter`
88
- for each criterion:
85
+ A demo plays like a person showing the app. Tell each chapter in beats with
86
+ `demo.say(line, steps)`: the line is spoken while its steps run on screen.
87
+ The demo shows only beats, so sign in, seed data and wait outside them. Show
88
+ a CLI step with `demo.terminal()`. The recorder, `@outerlayer/playwright`,
89
+ releases with the CLI: install it at the CLI's version first. The test, and
90
+ the rules a reviewer holds it to, are in
91
+ [references/demo.md](references/demo.md).
89
92
 
90
- import { expect, test } from "@outerlayer/playwright";
91
-
92
- test("a member signs in", async ({ page, demo }) => {
93
- await page.goto("/login");
94
- await demo.chapter("LOGIN-01", "Sign in", "The member signs in and lands on the dashboard.", async () => {
95
- await page.getByRole("button", { name: "Sign in" }).click();
96
- await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
97
- });
98
- });
99
-
100
- Commit the test: `work proofs --record` finds it by its chapter ids.
101
-
102
- Record each `proof: screenshot` criterion as a chapter too. Call `await
103
- demo.screenshot()` inside it, right after the `expect` that shows the result.
104
- Options: `{ fullPage: true }`, `{ masks: true }`. `emit demo` stores the frame
105
- when every check passed, or says why not.
106
-
107
- Install it with `npm install --save-dev @outerlayer/playwright`. Use the
108
- recorded criterion id as the first argument, or `null` for an opening scene.
109
- Keep each narration line short. Put the `expect` calls that prove the
110
- criterion inside the chapter: each is recorded as a check.
111
-
112
- Run the test. It writes `demo/manifest.json` and `demo/video.webm` in the
113
- test's output folder. Then emit the demo:
93
+ Commit the test: `work proofs --record` finds it by its chapter ids. Run it,
94
+ then emit the demo:
114
95
 
115
96
  outerlayer emit demo test-results/<test folder>/demo/manifest.json
116
97
 
117
- The command stores the whole demo as one video and uploads its bytes once.
118
- Each chapter is its own video proof with a time range in that video. A
119
- chapter whose checks all passed is bound to its criterion. A chapter with
120
- a failed check is stored unbound, and the command exits 1: fix the app and
121
- record again. The command needs `ffmpeg` and `espeak-ng` on PATH. Pass
122
- `--no-narration` when you cannot install `espeak-ng`. It refuses before it
123
- uploads anything when a chapter is out of order, a criterion id is not
124
- recorded, a line is too long, or a chapter's clip is over 8 MiB. A video over 8 MiB falls back to one clip
125
- for each chapter. A runner build has everything installed.
98
+ Pass `--output demo.webm` first and watch the demo. The command shows only
99
+ the beats and cuts each stretch in which the screen does not move and nothing
100
+ is said. It refuses a demo that still holds one over 2 s, a chapter id that is
101
+ not recorded, or a line too long for its beat. A chapter whose checks all
102
+ passed is bound to its criterion. A chapter with a failed check is stored
103
+ unbound, and the command exits 1: fix the app and record again. It needs
104
+ `ffmpeg` and `espeak-ng`. A runner build has both.
126
105
 
127
106
  ## The noise rule
128
107
 
@@ -0,0 +1,75 @@
1
+ # Write a demo
2
+
3
+ A demo is a reviewer's first look at the change. It plays like a person
4
+ showing the app: each step happens on screen while a line says what it is.
5
+ Setup, sign-ins and waits never reach the video.
6
+
7
+ ## The test
8
+
9
+ The fixture, `@outerlayer/playwright`, releases with the CLI at the same
10
+ version. `outerlayer --version` prints the CLI's version first. Before you
11
+ write the test, install the fixture at that version with the repository's
12
+ package manager. Commit that change with the test. Keep a newer version, and
13
+ keep a `workspace:` dependency as it is. Import `test` and `expect` from the
14
+ fixture:
15
+
16
+ import { expect, test } from "@outerlayer/playwright";
17
+
18
+ test("a member saves a build variable", async ({ page, demo }) => {
19
+ await signIn(page); // setup: outside every beat
20
+ await page.goto("/settings");
21
+ await demo.chapter("AC-7-02", "Save a variable", async () => {
22
+ await demo.say("The member saves a variable named NPM token.", async () => {
23
+ await page.getByLabel("Name").fill("NPM_TOKEN");
24
+ await page.getByRole("button", { name: "Save" }).click();
25
+ await expect(page.getByText("The variable is saved")).toBeVisible();
26
+ });
27
+ await page.reload(); // setup: the demo cuts it
28
+ await demo.say("After a reload, the list shows its name and no value.", async () => {
29
+ await expect(page.getByText("NPM_TOKEN")).toBeVisible();
30
+ await demo.screenshot();
31
+ });
32
+ });
33
+ });
34
+
35
+ Each beat lasts as long as its line. Inside a beat a pointer moves to each
36
+ click, `fill` types its text, and the page scrolls smoothly. Set
37
+ `OUTERLAYER_CLI` to the CLI so each beat is timed to its real line.
38
+
39
+ ## Rules
40
+
41
+ - One chapter for each criterion that declares `video` or `screenshot`, in
42
+ the criteria's order. Its first argument is the recorded id. `null` names
43
+ an opening scene, and only the first chapter may use it.
44
+ - One persona in one organization. Sign in once, before the first chapter.
45
+ Never sign out and in again to change state.
46
+ - Change state between beats: through the app where a screen exists, or
47
+ directly where none does. The demo leaves it out, so a long wait costs
48
+ nothing.
49
+ - One beat for each step a viewer should see. Its line says what happens,
50
+ in the present tense, in one or two short sentences. Do not read
51
+ criterion ids aloud.
52
+ - Inside a beat, move between pages through the app's own links. Reload a
53
+ list between beats.
54
+ - Put each `expect` that proves the criterion inside a beat: it is a check.
55
+ Call `await demo.screenshot()` right after the check that shows a
56
+ screenshot criterion's result.
57
+ - Show a step outside the browser with
58
+ `await demo.terminal(command, run)`. Return the command's real output from
59
+ `run`, and check it.
60
+ - Show a call to an API with `await demo.http({ method, url, body }, run)`
61
+ when a criterion's proof is an API response, or a step goes through the
62
+ API and no page shows it. Return the real `{ status, body }` from `run`.
63
+ - Point to the one element a line talks about on a busy page with
64
+ `await demo.highlight(locator)`, such as a status in a long list. Highlight
65
+ at most one element in a beat, and none where the element is plain to see.
66
+ - Turn off `demoOptions.animations` to keep the app's own transitions. Each
67
+ still and screenshot stops motion either way.
68
+
69
+ ## Before you emit
70
+
71
+ Render the demo with `outerlayer emit demo <manifest> --output demo.webm`
72
+ and watch it. Fix a beat that shows a loading screen, a sign-in or a step
73
+ its line does not name. The command exits 1 while the demo holds a frozen,
74
+ silent stretch over 2 s. When it notes that the fixture's version is not the
75
+ CLI's, install the version it names and record the demo again.