@osfactory/har 0.64.2 → 1.0.0-rc.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 (141) hide show
  1. package/dist/index.js +15675 -6536
  2. package/dist/prompts/system-authoring.md +155 -0
  3. package/dist/templates/adaptation-prompt-init.md +67 -43
  4. package/dist/templates/adaptation-prompt-maintain.md +38 -38
  5. package/dist/templates/agent-skills/har-maintain.md +2 -2
  6. package/dist/templates/agent-skills/setup-har.md +6 -4
  7. package/dist/templates/cursor-rule.mdc.template +3 -3
  8. package/dist/templates/har-boilerplate/docker-compose.agent.yml +1 -1
  9. package/dist/templates/har-boilerplate/harness.env +11 -155
  10. package/dist/templates/har-boilerplate/stages.json +51 -2
  11. package/dist/templates/har-boilerplate-cli/docker-compose.agent.yml +1 -1
  12. package/dist/templates/har-boilerplate-cli/harness.env +12 -138
  13. package/dist/templates/har-boilerplate-cli/stages.json +42 -2
  14. package/dist/templates/har-boilerplate-ios/harness.env +10 -126
  15. package/dist/templates/har-boilerplate-ios/stages.json +42 -2
  16. package/dist/templates/migration-prompt.md +54 -0
  17. package/dist/templates/plugins/custom-stage-skeleton.sh +11 -20
  18. package/dist/templates/plugins/gitleaks/.github/workflows/gitleaks.yml +1 -1
  19. package/dist/templates/plugins/gitleaks/.har/stages/GITLEAKS.md +1 -1
  20. package/dist/templates/plugins/gitleaks/.har/stages/secrets-scan.sh +8 -23
  21. package/dist/templates/plugins/gitleaks/README.md +1 -1
  22. package/dist/templates/plugins/gitleaks/template.manifest.json +20 -5
  23. package/dist/templates/plugins/kerno/.github/workflows/kerno.yml +1 -1
  24. package/dist/templates/plugins/kerno/.har/stages/backend-validation.sh +8 -23
  25. package/dist/templates/plugins/kerno/README.md +1 -1
  26. package/dist/templates/plugins/kerno/template.manifest.json +20 -9
  27. package/dist/templates/plugins/local-plugin-skeleton/README.md +46 -0
  28. package/dist/templates/plugins/playwright/.har/stages/browser-e2e.sh +8 -23
  29. package/dist/templates/plugins/playwright/template.manifest.json +36 -13
  30. package/dist/templates/plugins/rocketsim/.har/stages/rocketsim-flows.sh +8 -23
  31. package/dist/templates/plugins/rocketsim/template.manifest.json +20 -8
  32. package/dist/templates/plugins/semgrep/.har/stages/sast.sh +10 -26
  33. package/dist/templates/plugins/semgrep/README.md +1 -1
  34. package/dist/templates/plugins/semgrep/template.manifest.json +16 -7
  35. package/dist/templates/plugins/trivy/.har/stages/vuln-scan.sh +8 -23
  36. package/dist/templates/plugins/trivy/README.md +1 -1
  37. package/dist/templates/plugins/trivy/template.manifest.json +20 -8
  38. package/dist/templates/{har-boilerplate-cli/CLAUDE.agent.md → profiles/cli/docs/claude-agent/definition-of-done.md} +0 -42
  39. package/dist/templates/profiles/cli/docs/claude-agent/do-not.md +6 -0
  40. package/dist/templates/profiles/cli/docs/claude-agent/environment.md +12 -0
  41. package/dist/templates/profiles/cli/docs/claude-agent/project-commands.md +10 -0
  42. package/dist/templates/profiles/cli/docs/claude-agent/readiness.md +6 -0
  43. package/dist/templates/profiles/cli/docs/readme/for-coding-agents.md +9 -0
  44. package/dist/templates/profiles/cli/docs/readme/intro.md +7 -0
  45. package/dist/templates/profiles/cli/docs/readme/port-shared-services-cli-profile.md +25 -0
  46. package/dist/templates/profiles/cli/docs/readme/quick-start.md +24 -0
  47. package/dist/templates/profiles/cli/docs/readme/verification-contract.md +22 -0
  48. package/dist/templates/profiles/cli/docs/readme/what-s-in-here.md +27 -0
  49. package/dist/templates/profiles/cli/profile.manifest.json +56 -1
  50. package/dist/templates/profiles/default/docs/claude-agent/definition-of-done.md +24 -0
  51. package/dist/templates/profiles/default/docs/claude-agent/do-not.md +10 -0
  52. package/dist/templates/profiles/default/docs/claude-agent/environment.md +19 -0
  53. package/dist/templates/profiles/default/docs/claude-agent/project-commands.md +10 -0
  54. package/dist/templates/profiles/default/docs/claude-agent/readiness.md +12 -0
  55. package/dist/templates/profiles/default/docs/readme/architecture.md +11 -0
  56. package/dist/templates/profiles/default/docs/readme/for-coding-agents.md +9 -0
  57. package/dist/templates/profiles/default/docs/readme/intro.md +7 -0
  58. package/dist/templates/profiles/default/docs/readme/port-shared-services.md +41 -0
  59. package/dist/templates/profiles/default/docs/readme/quick-start.md +24 -0
  60. package/dist/templates/profiles/default/docs/readme/readiness-layers.md +16 -0
  61. package/dist/templates/profiles/default/docs/readme/verification-contract.md +17 -0
  62. package/dist/templates/profiles/default/docs/readme/what-s-in-here.md +28 -0
  63. package/dist/templates/profiles/default/profile.manifest.json +62 -1
  64. package/dist/templates/profiles/ios/docs/claude-agent/definition-of-done.md +23 -0
  65. package/dist/templates/profiles/ios/docs/claude-agent/do-not.md +6 -0
  66. package/dist/templates/profiles/ios/docs/claude-agent/environment.md +14 -0
  67. package/dist/templates/profiles/ios/docs/claude-agent/intro.md +3 -0
  68. package/dist/templates/profiles/ios/docs/claude-agent/project-commands.md +21 -0
  69. package/dist/templates/profiles/ios/docs/claude-agent/readiness.md +6 -0
  70. package/dist/templates/profiles/ios/docs/claude-agent/user-flow-validation-rocketsim.md +11 -0
  71. package/dist/templates/profiles/ios/docs/readme/configuration.md +7 -0
  72. package/dist/templates/profiles/ios/docs/readme/intro.md +7 -0
  73. package/dist/templates/profiles/ios/docs/readme/port-shared-services-ios-profile.md +25 -0
  74. package/dist/templates/profiles/ios/docs/readme/quick-start.md +22 -0
  75. package/dist/templates/profiles/ios/docs/readme/simulators.md +45 -0
  76. package/dist/templates/profiles/ios/docs/readme/user-flow-validation.md +9 -0
  77. package/dist/templates/profiles/ios/docs/readme/verification-contract.md +13 -0
  78. package/dist/templates/profiles/ios/docs/readme/what-s-in-here.md +27 -0
  79. package/dist/templates/profiles/ios/profile.manifest.json +59 -3
  80. package/dist/templates/runtime-bundles/pm2-runtime/attach.sh +8 -15
  81. package/dist/templates/runtime-bundles/pm2-runtime/env.template +1 -1
  82. package/dist/templates/runtime-bundles/pm2-runtime/stages/api-health.sh +9 -0
  83. package/dist/templates/runtime-bundles/shared-kernel/STAGES.md +32 -18
  84. package/dist/templates/runtime-bundles/shared-kernel/agent-cli.sh +35 -0
  85. package/dist/templates/runtime-bundles/shared-kernel/launch.sh +35 -0
  86. package/dist/templates/runtime-bundles/shared-kernel/lib/verify-runner.mjs +129 -0
  87. package/dist/templates/runtime-bundles/shared-kernel/preflight.sh +35 -0
  88. package/dist/templates/runtime-bundles/shared-kernel/setup-infra.sh +35 -0
  89. package/dist/templates/runtime-bundles/shared-kernel/stages/README.sh +1 -1
  90. package/dist/templates/runtime-bundles/shared-kernel/stages/readiness.sh +14 -0
  91. package/dist/templates/runtime-bundles/shared-kernel/teardown.sh +35 -0
  92. package/dist/templates/runtime-bundles/shared-kernel/verify.sh +35 -0
  93. package/dist/templates/shared-docs/claude-agent/intro.md +3 -0
  94. package/dist/templates/shared-docs/readme/maintaining-this-harness.md +14 -0
  95. package/dist/templates/shared-docs/readme/run-history.md +5 -0
  96. package/dist/templates/shared-docs/readme/session-lifecycle.md +20 -0
  97. package/package.json +1 -1
  98. package/dist/templates/har-boilerplate/CLAUDE.agent.md +0 -83
  99. package/dist/templates/har-boilerplate/README.md +0 -199
  100. package/dist/templates/har-boilerplate/STAGES.md +0 -99
  101. package/dist/templates/har-boilerplate/agent-cli.sh +0 -225
  102. package/dist/templates/har-boilerplate/agent-slot.sh +0 -850
  103. package/dist/templates/har-boilerplate/attach.sh +0 -22
  104. package/dist/templates/har-boilerplate/ecosystem.agent.template.cjs +0 -52
  105. package/dist/templates/har-boilerplate/env.template +0 -40
  106. package/dist/templates/har-boilerplate/launch.sh +0 -323
  107. package/dist/templates/har-boilerplate/preflight.sh +0 -32
  108. package/dist/templates/har-boilerplate/provision-toolchain.sh +0 -766
  109. package/dist/templates/har-boilerplate/setup-infra.sh +0 -178
  110. package/dist/templates/har-boilerplate/stages/README.sh +0 -11
  111. package/dist/templates/har-boilerplate/teardown.sh +0 -87
  112. package/dist/templates/har-boilerplate/verify.sh +0 -249
  113. package/dist/templates/har-boilerplate-cli/README.md +0 -157
  114. package/dist/templates/har-boilerplate-cli/STAGES.md +0 -99
  115. package/dist/templates/har-boilerplate-cli/agent-cli.sh +0 -160
  116. package/dist/templates/har-boilerplate-cli/agent-slot.sh +0 -832
  117. package/dist/templates/har-boilerplate-cli/launch.sh +0 -216
  118. package/dist/templates/har-boilerplate-cli/preflight.sh +0 -28
  119. package/dist/templates/har-boilerplate-cli/provision-toolchain.sh +0 -766
  120. package/dist/templates/har-boilerplate-cli/setup-infra.sh +0 -178
  121. package/dist/templates/har-boilerplate-cli/stages/README.sh +0 -11
  122. package/dist/templates/har-boilerplate-cli/teardown.sh +0 -66
  123. package/dist/templates/har-boilerplate-cli/verify.sh +0 -210
  124. package/dist/templates/har-boilerplate-ios/ADAPT-PROMPT.md +0 -63
  125. package/dist/templates/har-boilerplate-ios/CLAUDE.agent.md +0 -90
  126. package/dist/templates/har-boilerplate-ios/README.md +0 -173
  127. package/dist/templates/har-boilerplate-ios/STAGES.md +0 -99
  128. package/dist/templates/har-boilerplate-ios/agent-cli.sh +0 -149
  129. package/dist/templates/har-boilerplate-ios/agent-slot.sh +0 -479
  130. package/dist/templates/har-boilerplate-ios/launch.sh +0 -206
  131. package/dist/templates/har-boilerplate-ios/provision-toolchain.sh +0 -766
  132. package/dist/templates/har-boilerplate-ios/setup-infra.sh +0 -112
  133. package/dist/templates/har-boilerplate-ios/simulator.sh +0 -492
  134. package/dist/templates/har-boilerplate-ios/stages/README.sh +0 -11
  135. package/dist/templates/har-boilerplate-ios/teardown.sh +0 -68
  136. package/dist/templates/har-boilerplate-ios/verify.sh +0 -185
  137. package/dist/templates/runtime-bundles/pm2-runtime/README.md +0 -4
  138. package/dist/templates/runtime-bundles/shared-kernel/README.md +0 -3
  139. package/dist/templates/runtime-bundles/shared-kernel/provision-toolchain.sh +0 -766
  140. package/dist/templates/runtime-bundles/xcode-sim/README.md +0 -4
  141. package/dist/templates/runtime-bundles/xcode-sim/simulator.sh +0 -492
@@ -32,9 +32,11 @@
32
32
  {
33
33
  "id": "verify",
34
34
  "kind": "verify",
35
- "description": "Verification pipeline (quick smoke by default; --full runs the registry's verificationStages)",
35
+ "description": "Verification pipeline: runs stages.json verificationStages in order (tier \"quick\" by default; --full runs the whole list)",
36
36
  "command": "./.har/verify.sh {agentId}",
37
- "acceptsArgs": ["--full"],
37
+ "acceptsArgs": [
38
+ "--full"
39
+ ],
38
40
  "artifacts": [
39
41
  {
40
42
  "path": ".har/artifacts",
@@ -61,6 +63,44 @@
61
63
  "kind": "teardown",
62
64
  "description": "Remove worktree and env file for the slot",
63
65
  "command": "./.har/teardown.sh {agentId}"
66
+ },
67
+ {
68
+ "id": "build",
69
+ "kind": "test",
70
+ "tier": "quick",
71
+ "description": "Xcode build smoke (compile-only, unsigned)",
72
+ "command": "${XCODEBUILD_BIN:-xcodebuild} build ${XC_FLAGS} -scheme \"${XC_SCHEME}\" -destination \"${XC_DESTINATION}\" -derivedDataPath \"${XC_DERIVED}\" CODE_SIGNING_ALLOWED=NO | xcbeautify 2>/dev/null || ${XCODEBUILD_BIN:-xcodebuild} build ${XC_FLAGS} -scheme \"${XC_SCHEME}\" -destination \"${XC_DESTINATION}\" -derivedDataPath \"${XC_DERIVED}\" CODE_SIGNING_ALLOWED=NO",
73
+ "requiresAgentId": true
74
+ },
75
+ {
76
+ "id": "unit-tests",
77
+ "kind": "test",
78
+ "tier": "full",
79
+ "description": "Xcode unit tests (signed: simulator installs the host app)",
80
+ "command": "${XCODEBUILD_BIN:-xcodebuild} test ${XC_FLAGS} -scheme \"${XC_SCHEME}\" -destination \"${XC_DESTINATION}\" -derivedDataPath \"${XC_DERIVED}\" | xcbeautify 2>/dev/null || ${XCODEBUILD_BIN:-xcodebuild} test ${XC_FLAGS} -scheme \"${XC_SCHEME}\" -destination \"${XC_DESTINATION}\" -derivedDataPath \"${XC_DERIVED}\"",
81
+ "requiresAgentId": true
82
+ },
83
+ {
84
+ "id": "lint",
85
+ "kind": "test",
86
+ "tier": "full",
87
+ "description": "SwiftLint (skips when not installed)",
88
+ "command": "command -v \"${HARNESS_SWIFTLINT_CMD:-swiftlint}\" >/dev/null 2>&1 && \"${HARNESS_SWIFTLINT_CMD:-swiftlint}\" --quiet || echo \"swiftlint not installed — skipping\"",
89
+ "requiresAgentId": true
90
+ },
91
+ {
92
+ "id": "readiness",
93
+ "kind": "test",
94
+ "tier": "full",
95
+ "description": "Project readiness smoke (HARNESS_READINESS_CMD)",
96
+ "script": "stages/readiness.sh",
97
+ "requiresAgentId": true
64
98
  }
99
+ ],
100
+ "verificationStages": [
101
+ "build",
102
+ "unit-tests",
103
+ "lint",
104
+ "readiness"
65
105
  ]
66
106
  }
@@ -0,0 +1,54 @@
1
+ Migrate the `.har/` harness in this repository from the pre-1.0 shape to the 1.0 configuration surface.
2
+
3
+ ## What changes and why
4
+
5
+ In 1.0 the harness machinery lives once, in the `@osfactory/har` package. `.har/` keeps only what is yours:
6
+
7
+ - **config** — `harness.env` (pure `KEY=value`, schema-validated)
8
+ - **stages** — `stages.json` + `.har/stages/*.sh` (verification as data)
9
+ - **hooks** — `.har/hooks/{pre-launch,post-launch,pre-verify,pre-teardown,post-teardown}.sh` (custom lifecycle behavior)
10
+ - **plugins** — `.har/plugins/<id>/` local plugins for anything bigger (`har plugin create <id>`)
11
+
12
+ The `./.har/*.sh` entry points become thin shims (`exec har env … "$@"` with a pinned `npx` fallback), so every surface — raw scripts, `har env`, MCP tools — writes the same run/validation records. Your muscle memory (`./.har/launch.sh 1`, `./.har/verify.sh 1 --full`, `har env launch 1`) keeps working before, during, and after.
13
+
14
+ {{MIGRATION_SECTION}}
15
+
16
+ ## Step 3 — Lift each residue item
17
+
18
+ For every row in the residue table above, read its backup under `.har/migrate/backup/` and move the project-specific behavior into the 1.0 model:
19
+
20
+ - **config** → a `harness.env` schema key (see `@har/schemas` HarnessEnvSchema). Custom keys the schema rejects: keep the value inside the hook/stage that consumes it.
21
+ - **stage** → a `stages.json` entry (plain `command`, or a script in `.har/stages/`), listed in `verificationStages` if it gates verify.
22
+ - **hook** → the matching `.har/hooks/<hook>.sh`. Hooks receive `HAR_HOOK`, `AGENT_ID`, `WORK_DIR`, `ENV_FILE`, `HAR_HARNESS_DIR`, `HAR_PORT_<NAME>` (contract `HAR_HOOK_CONTRACT=1`). Failing `pre-*` hooks abort the operation; `post-*` failures warn unless `HARNESS_HOOK_POST_FAILURE=fail`. Make hooks executable.
23
+ - **plugin** → `har plugin create <id>` scaffolds a local plugin in `.har/plugins/<id>/`; then `har env add-plugin <id>`.
24
+ - **review** → usually nothing to keep (the package runtime covers it) — confirm, then move on.
25
+
26
+ Compare each backup against its replacement only for **project-specific** logic. Do not restore vendored machinery — that is what 1.0 removes.
27
+
28
+ ## Step 4 — Heavily customized harness? Consider eject
29
+
30
+ If the backups show deep patches to the machinery itself (not just config/stages/hooks material), `har env eject` vendors the full runtime into `.har/runtime/` and hands you ownership of the scripts — explicit, supported, reversible with `har env adopt`. Prefer lifting into hooks when the patch is a lifecycle side effect; eject only when you truly need to own the runtime.
31
+
32
+ ## Step 5 — Verify the migration
33
+
34
+ 1. `har env doctor` — must pass (contract: 1.0, no errors).
35
+ 2. `har env maintain` — drift report should show only files you deliberately adapted.
36
+ 3. Full verify on **every configured agent slot** that is in use; at minimum:
37
+ - `har env launch 1`
38
+ - `har env verify 1 --full` (or `./.har/verify.sh 1 --full` — same records either way)
39
+ - `har env complete 1` (or `har env teardown 1`)
40
+ 4. Exercise anything you lifted into hooks/stages (e.g. per-slot data stores exist in the work dir, custom checks run in `--full`).
41
+
42
+ ## Step 6 — Finalize
43
+
44
+ Record the migration and clean up the migration artifacts (`.har/migrate/`, this prompt):
45
+
46
+ har env maintain --finalize --summary "Migrated pre-1.0 harness to the 1.0 config surface: <what you lifted where>"
47
+
48
+ ## Rules
49
+
50
+ 1. Never edit `.har/manifest.json` by hand — it is managed by the har CLI.
51
+ 2. Do not delete `.har/migrate/backup/` until finalize — it is the only copy of the pre-1.0 adaptations.
52
+ 3. Keep `stages.json` stage ids stable — run records and Mission Control reference them.
53
+ 4. Update `.har/README.md` and `.har/CLAUDE.agent.md` if commands or workflow notes changed.
54
+ 5. Commit the migrated harness (shims, `harness.env`, `stages.json`, `.har/hooks/`) once verified — `.har/migrate/` and this prompt are transient and stay untracked.
@@ -12,31 +12,22 @@
12
12
  # Usage: ./.har/stages/__STAGE_ID__.sh <agent-id> [extra args...]
13
13
  set -euo pipefail
14
14
 
15
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
- HARNESS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
15
+ # 1.0 stage surface: the runner exports WORK_DIR, ENV_FILE, AGENT_ID and
16
+ # HAR_HARNESS_DIR, with harness.env and the slot env file already sourced —
17
+ # agent-slot.sh is retired (1.0 migration).
18
+ HARNESS_DIR="${HAR_HARNESS_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
17
19
  REPO_ROOT="$(cd "$HARNESS_DIR/.." && pwd)"
18
- # agent-slot.sh expects SCRIPT_DIR to be .har/ (slot registry lives there)
19
- SCRIPT_DIR="$HARNESS_DIR"
20
20
 
21
- # shellcheck source=/dev/null
22
- source "$HARNESS_DIR/harness.env"
23
- # shellcheck source=/dev/null
24
- source "$HARNESS_DIR/agent-slot.sh"
21
+ AGENT_ID="${1:-${AGENT_ID:?Usage: __STAGE_ID__.sh <agent-id> [extra args...]}}"
22
+ now_ms() { node -e 'process.stdout.write(String(Date.now()))' 2>/dev/null || echo 0; }
25
23
 
26
- AGENT_ID="${1:?Usage: __STAGE_ID__.sh <agent-id> [extra args...]}"
27
- validate_agent_id "$AGENT_ID"
28
-
29
- ENV_FILE="$(resolve_agent_env_file "$AGENT_ID" "$REPO_ROOT")" || {
30
- echo "No .env.agent.${AGENT_ID} found." >&2
31
- har_suggest_launch "$AGENT_ID" >&2
32
- exit 1
24
+ # JSON-escape step output; truncate to 50 lines in node (avoids SIGPIPE under pipefail).
25
+ escape_step_output() {
26
+ printf '%s' "$1" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const s=d.trim().split('\n').slice(0,50).join('\n');process.stdout.write(JSON.stringify(s))})" 2>/dev/null || echo '""'
33
27
  }
34
- set -a
35
- # shellcheck source=/dev/null
36
- source "$ENV_FILE"
37
- set +a
38
28
 
39
- WORK_DIR="$(resolve_agent_work_dir "$ENV_FILE")"
29
+ ENV_FILE="${ENV_FILE:?No slot env for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
30
+ WORK_DIR="${WORK_DIR:?No slot work dir for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
40
31
  ARTIFACTS_DIR="$HARNESS_DIR/artifacts/__STAGE_ID__"
41
32
  mkdir -p "$ARTIFACTS_DIR"
42
33
 
@@ -1,5 +1,5 @@
1
1
  # Secrets scanning with the official Gitleaks action.
2
- # Installed by `har env add-plugin gitleaks` (skip with --skip-ci).
2
+ # Installed by `har env add-plugin gitleaks --with-ci` (CI files are skipped by default).
3
3
  #
4
4
  # This CI run is what produces org-level scanning evidence that compliance
5
5
  # platforms (Vanta, Drata, …) can ingest via your GitHub organization.
@@ -63,7 +63,7 @@ same config governs local stage runs and CI.
63
63
 
64
64
  ## CI and compliance platforms (Vanta, Drata, …)
65
65
 
66
- The optional workflow `.github/workflows/gitleaks.yml` (skipped with `--skip-ci`)
66
+ The optional workflow `.github/workflows/gitleaks.yml` (installed only with `--with-ci`)
67
67
  runs the official [`gitleaks/gitleaks-action`](https://github.com/gitleaks/gitleaks-action)
68
68
  on pushes and pull requests.
69
69
 
@@ -12,21 +12,16 @@
12
12
  # See: ./.har/stages/GITLEAKS.md for the adaptation guide.
13
13
  set -euo pipefail
14
14
 
15
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
- HARNESS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
15
+ # 1.0 stage surface: the runner exports WORK_DIR, ENV_FILE, AGENT_ID and
16
+ # HAR_HARNESS_DIR, with harness.env and the slot env file already sourced —
17
+ # agent-slot.sh is retired (1.0 migration).
18
+ HARNESS_DIR="${HAR_HARNESS_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
17
19
  REPO_ROOT="$(cd "$HARNESS_DIR/.." && pwd)"
18
- # agent-slot.sh expects SCRIPT_DIR to be .har/ (slot registry lives there)
19
- SCRIPT_DIR="$HARNESS_DIR"
20
20
 
21
- # shellcheck source=/dev/null
22
- source "$HARNESS_DIR/harness.env"
23
- # shellcheck source=/dev/null
24
- source "$HARNESS_DIR/agent-slot.sh"
25
-
26
- AGENT_ID="${1:?Usage: secrets-scan.sh <agent-id> [dir|git]}"
21
+ AGENT_ID="${1:-${AGENT_ID:?Usage: secrets-scan.sh <agent-id> [dir|git]}}"
27
22
  MODE="${2:-dir}"
28
23
 
29
- validate_agent_id "$AGENT_ID"
24
+ now_ms() { node -e 'process.stdout.write(String(Date.now()))' 2>/dev/null || echo 0; }
30
25
 
31
26
  if [ "$MODE" != "dir" ] && [ "$MODE" != "git" ]; then
32
27
  echo "Error: unknown mode '$MODE' — expected 'dir' or 'git'." >&2
@@ -53,18 +48,8 @@ REPORT_PATH="$ARTIFACT_DIR/report.json"
53
48
  SCAN_LOG="$ARTIFACT_DIR/gitleaks.log"
54
49
 
55
50
  # ── Resolve agent env ─────────────────────────────────────────────────────────
56
- ENV_FILE="$(resolve_agent_env_file "$AGENT_ID" "$REPO_ROOT")" || {
57
- echo "No .env.agent.${AGENT_ID} found." >&2
58
- har_suggest_launch "$AGENT_ID" >&2
59
- exit 1
60
- }
61
-
62
- set -a
63
- # shellcheck source=/dev/null
64
- source "$ENV_FILE"
65
- set +a
66
-
67
- WORK_DIR="$(resolve_agent_work_dir "$ENV_FILE")"
51
+ ENV_FILE="${ENV_FILE:?No slot env for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
52
+ WORK_DIR="${WORK_DIR:?No slot work dir for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
68
53
 
69
54
  GITLEAKS_VERSION="$(gitleaks version 2>/dev/null | head -1 || echo unknown)"
70
55
  log "gitleaks ${GITLEAKS_VERSION} — ${MODE} scan of $WORK_DIR"
@@ -16,7 +16,7 @@ What it adds:
16
16
  - `.gitleaks.toml` — default config extending the built-in ruleset with harness
17
17
  allowlists (skipped if the repo already has one)
18
18
  - `.github/workflows/gitleaks.yml` — official `gitleaks/gitleaks-action` CI
19
- workflow (skip with `--skip-ci`)
19
+ workflow (opt in with `--with-ci`)
20
20
 
21
21
  Requirements: the `gitleaks` binary on PATH (`brew install gitleaks` or a
22
22
  [release binary](https://github.com/gitleaks/gitleaks/releases)). No package.json
@@ -16,15 +16,30 @@
16
16
  "kind": "directory",
17
17
  "description": "Redacted JSON findings report and scan log"
18
18
  }
19
- ]
19
+ ],
20
+ "tier": "full"
20
21
  },
21
22
  "files": [
22
- { "src": ".har/stages/secrets-scan.sh", "dest": ".har/stages/secrets-scan.sh", "executable": true },
23
- { "src": ".har/stages/GITLEAKS.md", "dest": ".har/stages/GITLEAKS.md" }
23
+ {
24
+ "src": ".har/stages/secrets-scan.sh",
25
+ "dest": ".har/stages/secrets-scan.sh",
26
+ "executable": true
27
+ },
28
+ {
29
+ "src": ".har/stages/GITLEAKS.md",
30
+ "dest": ".har/stages/GITLEAKS.md"
31
+ }
24
32
  ],
25
33
  "optionalFiles": [
26
- { "src": ".gitleaks.toml", "dest": ".gitleaks.toml" },
27
- { "src": ".github/workflows/gitleaks.yml", "dest": ".github/workflows/gitleaks.yml", "skipFlag": "skipCi" }
34
+ {
35
+ "src": ".gitleaks.toml",
36
+ "dest": ".gitleaks.toml"
37
+ },
38
+ {
39
+ "src": ".github/workflows/gitleaks.yml",
40
+ "dest": ".github/workflows/gitleaks.yml",
41
+ "skipFlag": "skipCi"
42
+ }
28
43
  ],
29
44
  "nextSteps": [
30
45
  "Install gitleaks: brew install gitleaks — or a release binary from https://github.com/gitleaks/gitleaks/releases",
@@ -6,7 +6,7 @@
6
6
  # 2. Your app running and reachable at the SUT URL, with its database migrated/seeded.
7
7
  # 3. A Kerno agent bound to this checkout (`kerno init`) with a committed suite in .kerno/.
8
8
  #
9
- # The stage sources the HAR slot machinery (.har/harness.env, agent-slot.sh, .env.agent.<id>),
9
+ # The stage relies on the HAR stage runner (harness.env + slot env exported by `har env verify`),
10
10
  # so the supported path is to run it inside a launched HAR slot. Adapt the "start app" and
11
11
  # "kerno init" steps for your stack. Remove `if: false` once wired up.
12
12
  name: Kerno backend validation
@@ -9,19 +9,14 @@
9
9
  # See: ./.har/stages/KERNO.md for the full setup + adaptation guide.
10
10
  set -euo pipefail
11
11
 
12
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
- HARNESS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
+ # 1.0 stage surface: the runner exports WORK_DIR, ENV_FILE, AGENT_ID and
13
+ # HAR_HARNESS_DIR, with harness.env and the slot env file already sourced —
14
+ # agent-slot.sh is retired (1.0 migration).
15
+ HARNESS_DIR="${HAR_HARNESS_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
14
16
  REPO_ROOT="$(cd "$HARNESS_DIR/.." && pwd)"
15
- # agent-slot.sh expects SCRIPT_DIR to be .har/ (slot registry lives there)
16
- SCRIPT_DIR="$HARNESS_DIR"
17
17
 
18
- # shellcheck source=/dev/null
19
- source "$HARNESS_DIR/harness.env"
20
- # shellcheck source=/dev/null
21
- source "$HARNESS_DIR/agent-slot.sh"
22
-
23
- AGENT_ID="${1:?Usage: backend-validation.sh <agent-id>}"
24
- validate_agent_id "$AGENT_ID"
18
+ AGENT_ID="${1:-${AGENT_ID:?Usage: backend-validation.sh <agent-id>}}"
19
+ now_ms() { node -e 'process.stdout.write(String(Date.now()))' 2>/dev/null || echo 0; }
25
20
 
26
21
  log() { echo "==> [backend-validation agent-$AGENT_ID] $*" >&2; }
27
22
 
@@ -81,18 +76,8 @@ fi
81
76
  trap cleanup EXIT
82
77
 
83
78
  # ── Resolve agent env + slot target ───────────────────────────────────────────
84
- ENV_FILE="$(resolve_agent_env_file "$AGENT_ID" "$REPO_ROOT")" || {
85
- echo "No .env.agent.${AGENT_ID} found." >&2
86
- har_suggest_launch "$AGENT_ID" >&2
87
- exit 1
88
- }
89
-
90
- set -a
91
- # shellcheck source=/dev/null
92
- source "$ENV_FILE"
93
- set +a
94
-
95
- WORK_DIR="$(resolve_agent_work_dir "$ENV_FILE")"
79
+ ENV_FILE="${ENV_FILE:?No slot env for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
80
+ WORK_DIR="${WORK_DIR:?No slot work dir for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
96
81
 
97
82
  # SUT URL: prefer an explicit override, then the app's own SITE_URL (both the default
98
83
  # web profile and single-port apps like Next.js set SITE_URL to the running app), then a
@@ -15,7 +15,7 @@ har env add-plugin kerno
15
15
  | `.har/stages/backend-validation.sh` | Stage runner. Re-runs the Kerno suite against the running slot over REST |
16
16
  | `.har/stages/KERNO.md` | Setup and adaptation guide: prerequisites, the one-agent rule, artifacts |
17
17
  | `tests/kerno/README.md` | This file |
18
- | `.github/workflows/kerno.yml` | Optional CI workflow (skip with `--skip-ci`) |
18
+ | `.github/workflows/kerno.yml` | Optional CI workflow (opt in with `--with-ci`) |
19
19
 
20
20
  ## Workflow
21
21
 
@@ -2,10 +2,6 @@
2
2
  "id": "kerno",
3
3
  "stageId": "backend-validation",
4
4
  "verificationStages": [
5
- "typecheck",
6
- "unit-tests",
7
- "api-health",
8
- "lint",
9
5
  "backend-validation"
10
6
  ],
11
7
  "stage": {
@@ -24,15 +20,30 @@
24
20
  "path": ".har/artifacts/backend-validation/report.json",
25
21
  "kind": "report"
26
22
  }
27
- ]
23
+ ],
24
+ "tier": "full"
28
25
  },
29
26
  "files": [
30
- { "src": ".har/stages/backend-validation.sh", "dest": ".har/stages/backend-validation.sh", "executable": true },
31
- { "src": ".har/stages/KERNO.md", "dest": ".har/stages/KERNO.md" },
32
- { "src": "README.md", "dest": "tests/kerno/README.md" }
27
+ {
28
+ "src": ".har/stages/backend-validation.sh",
29
+ "dest": ".har/stages/backend-validation.sh",
30
+ "executable": true
31
+ },
32
+ {
33
+ "src": ".har/stages/KERNO.md",
34
+ "dest": ".har/stages/KERNO.md"
35
+ },
36
+ {
37
+ "src": "README.md",
38
+ "dest": "tests/kerno/README.md"
39
+ }
33
40
  ],
34
41
  "optionalFiles": [
35
- { "src": ".github/workflows/kerno.yml", "dest": ".github/workflows/kerno.yml", "skipFlag": "skipCi" }
42
+ {
43
+ "src": ".github/workflows/kerno.yml",
44
+ "dest": ".github/workflows/kerno.yml",
45
+ "skipFlag": "skipCi"
46
+ }
36
47
  ],
37
48
  "nextSteps": [
38
49
  "npm install -g @kerno/cli",
@@ -0,0 +1,46 @@
1
+ # __PLUGIN_ID__ (local HAR plugin)
2
+
3
+ Project-owned plugin scaffolded by `har plugin create __PLUGIN_ID__`. It lives in
4
+ `.har/plugins/__PLUGIN_ID__/` and is committed with the repository — HAR never
5
+ overwrites it on upgrade.
6
+
7
+ ## Layout
8
+
9
+ | File | Purpose |
10
+ | --- | --- |
11
+ | `template.manifest.json` | What the plugin installs and which stages it registers |
12
+ | `stages/__PLUGIN_ID__.sh` | The stage script (HAR stage contract — see `.har/STAGES.md`) |
13
+ | `README.md` | This file — document what the stage checks and why |
14
+
15
+ ## Develop
16
+
17
+ 1. Implement the `TODO` block in `stages/__PLUGIN_ID__.sh`.
18
+ 2. Install (or reinstall after changes) into the harness:
19
+
20
+ ```bash
21
+ har env add-plugin __PLUGIN_ID__ --force
22
+ ```
23
+
24
+ This copies the files listed in `template.manifest.json` into place and
25
+ registers the plugin's stages in `.har/stages.json` — exactly like a
26
+ bundled, npm, or git plugin.
27
+
28
+ 3. Run it against a live slot:
29
+
30
+ ```bash
31
+ ./.har/stages/__PLUGIN_ID__.sh 1
32
+ ```
33
+
34
+ For a simple one-liner check you may not need a plugin at all — register a
35
+ command stage directly in `.har/stages.json` (see `.har/STAGES.md`).
36
+
37
+ ## Publish (optional)
38
+
39
+ The format is identical across all plugin sources — publishing requires zero
40
+ format changes:
41
+
42
+ - **npm**: add a `package.json` next to `template.manifest.json`, then
43
+ `npm publish`. Consumers run `har env add-plugin @your-scope/__PLUGIN_ID__`.
44
+ - **git**: push this directory (manifest at the repo root, or under
45
+ `plugins/__PLUGIN_ID__/`). Consumers run
46
+ `har env add-plugin github:your-org/your-repo`.
@@ -6,34 +6,19 @@
6
6
  # Prerequisite: ./.har/launch.sh <agent-id>
7
7
  set -euo pipefail
8
8
 
9
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
- HARNESS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
9
+ # 1.0 stage surface: the runner exports WORK_DIR, ENV_FILE, AGENT_ID and
10
+ # HAR_HARNESS_DIR, with harness.env and the slot env file already sourced —
11
+ # agent-slot.sh is retired (1.0 migration).
12
+ HARNESS_DIR="${HAR_HARNESS_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
11
13
  REPO_ROOT="$(cd "$HARNESS_DIR/.." && pwd)"
12
- # agent-slot.sh expects SCRIPT_DIR to be .har/ (slot registry lives there)
13
- SCRIPT_DIR="$HARNESS_DIR"
14
14
 
15
- # shellcheck source=/dev/null
16
- source "$HARNESS_DIR/harness.env"
17
- # shellcheck source=/dev/null
18
- source "$HARNESS_DIR/agent-slot.sh"
19
-
20
- AGENT_ID="${1:?Usage: browser-e2e.sh <agent-id>}"
21
- validate_agent_id "$AGENT_ID"
15
+ AGENT_ID="${1:-${AGENT_ID:?Usage: browser-e2e.sh <agent-id>}}"
16
+ now_ms() { node -e 'process.stdout.write(String(Date.now()))'; }
22
17
 
23
18
  log() { echo "==> [browser-e2e agent-$AGENT_ID] $*" >&2; }
24
19
 
25
- ENV_FILE="$(resolve_agent_env_file "$AGENT_ID" "$REPO_ROOT")" || {
26
- echo "No .env.agent.${AGENT_ID} found." >&2
27
- har_suggest_launch "$AGENT_ID" >&2
28
- exit 1
29
- }
30
-
31
- set -a
32
- # shellcheck source=/dev/null
33
- source "$ENV_FILE"
34
- set +a
35
-
36
- WORK_DIR="$(resolve_agent_work_dir "$ENV_FILE")"
20
+ ENV_FILE="${ENV_FILE:?No slot env for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
21
+ WORK_DIR="${WORK_DIR:?No slot work dir for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
37
22
  FE_PORT="${FE_PORT:-$(( HARNESS_FE_BASE_PORT + AGENT_ID * 10 ))}"
38
23
  API_PORT="${API_PORT:-$(( HARNESS_API_BASE_PORT + AGENT_ID * 10 ))}"
39
24
 
@@ -2,10 +2,6 @@
2
2
  "id": "playwright",
3
3
  "stageId": "browser-e2e",
4
4
  "verificationStages": [
5
- "typecheck",
6
- "unit-tests",
7
- "api-health",
8
- "lint",
9
5
  "browser-e2e"
10
6
  ],
11
7
  "stage": {
@@ -24,19 +20,46 @@
24
20
  "path": ".har/artifacts/browser-e2e/playwright-report",
25
21
  "kind": "report"
26
22
  }
27
- ]
23
+ ],
24
+ "tier": "full"
28
25
  },
29
26
  "files": [
30
- { "src": ".har/stages/browser-e2e.sh", "dest": ".har/stages/browser-e2e.sh", "executable": true },
31
- { "src": ".har/stages/PLAYWRIGHT.md", "dest": ".har/stages/PLAYWRIGHT.md" },
32
- { "src": "playwright.config.js", "dest": "playwright.config.js" },
33
- { "src": "tests/frontend/smoke.spec.js", "dest": "tests/frontend/smoke.spec.js" },
34
- { "src": "tests/api/health.spec.js", "dest": "tests/api/health.spec.js" },
35
- { "src": "tests/a11y/smoke.spec.js", "dest": "tests/a11y/smoke.spec.js" },
36
- { "src": "README.md", "dest": "tests/playwright/README.md" }
27
+ {
28
+ "src": ".har/stages/browser-e2e.sh",
29
+ "dest": ".har/stages/browser-e2e.sh",
30
+ "executable": true
31
+ },
32
+ {
33
+ "src": ".har/stages/PLAYWRIGHT.md",
34
+ "dest": ".har/stages/PLAYWRIGHT.md"
35
+ },
36
+ {
37
+ "src": "playwright.config.js",
38
+ "dest": "playwright.config.js"
39
+ },
40
+ {
41
+ "src": "tests/frontend/smoke.spec.js",
42
+ "dest": "tests/frontend/smoke.spec.js"
43
+ },
44
+ {
45
+ "src": "tests/api/health.spec.js",
46
+ "dest": "tests/api/health.spec.js"
47
+ },
48
+ {
49
+ "src": "tests/a11y/smoke.spec.js",
50
+ "dest": "tests/a11y/smoke.spec.js"
51
+ },
52
+ {
53
+ "src": "README.md",
54
+ "dest": "tests/playwright/README.md"
55
+ }
37
56
  ],
38
57
  "optionalFiles": [
39
- { "src": ".github/workflows/playwright.yml", "dest": ".github/workflows/playwright.yml", "skipFlag": "skipCi" }
58
+ {
59
+ "src": ".github/workflows/playwright.yml",
60
+ "dest": ".github/workflows/playwright.yml",
61
+ "skipFlag": "skipCi"
62
+ }
40
63
  ],
41
64
  "merge": {
42
65
  "package.json": "package.fragment.json"
@@ -10,21 +10,16 @@
10
10
  # See: ./.har/stages/ROCKETSIM.md for the full authoring guide.
11
11
  set -euo pipefail
12
12
 
13
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
- HARNESS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
13
+ # 1.0 stage surface: the runner exports WORK_DIR, ENV_FILE, AGENT_ID and
14
+ # HAR_HARNESS_DIR, with harness.env and the slot env file already sourced —
15
+ # agent-slot.sh is retired (1.0 migration).
16
+ HARNESS_DIR="${HAR_HARNESS_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
15
17
  REPO_ROOT="$(cd "$HARNESS_DIR/.." && pwd)"
16
- # agent-slot.sh expects SCRIPT_DIR to be .har/ (slot registry lives there)
17
- SCRIPT_DIR="$HARNESS_DIR"
18
18
 
19
- # shellcheck source=/dev/null
20
- source "$HARNESS_DIR/harness.env"
21
- # shellcheck source=/dev/null
22
- source "$HARNESS_DIR/agent-slot.sh"
23
-
24
- AGENT_ID="${1:?Usage: rocketsim-flows.sh <agent-id> [flow-name]}"
19
+ AGENT_ID="${1:-${AGENT_ID:?Usage: rocketsim-flows.sh <agent-id> [flow-name]}}"
25
20
  FLOW_FILTER="${2:-}"
26
21
 
27
- validate_agent_id "$AGENT_ID"
22
+ now_ms() { node -e 'process.stdout.write(String(Date.now()))' 2>/dev/null || echo 0; }
28
23
 
29
24
  log() { echo "==> [rocketsim agent-$AGENT_ID] $*" >&2; }
30
25
 
@@ -43,18 +38,8 @@ if ! rocketsim doctor --quiet 2>/dev/null; then
43
38
  fi
44
39
 
45
40
  # ── Resolve agent env ─────────────────────────────────────────────────────────
46
- ENV_FILE="$(resolve_agent_env_file "$AGENT_ID" "$REPO_ROOT")" || {
47
- echo "No .env.agent.${AGENT_ID} found." >&2
48
- har_suggest_launch "$AGENT_ID" >&2
49
- exit 1
50
- }
51
-
52
- set -a
53
- # shellcheck source=/dev/null
54
- source "$ENV_FILE"
55
- set +a
56
-
57
- WORK_DIR="$(resolve_agent_work_dir "$ENV_FILE")"
41
+ ENV_FILE="${ENV_FILE:?No slot env for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
42
+ WORK_DIR="${WORK_DIR:?No slot work dir for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
58
43
 
59
44
  # ── Discover flows ─────────────────────────────────────────────────────────────
60
45
  FLOWS_DIR="$WORK_DIR/flows"
@@ -2,9 +2,6 @@
2
2
  "id": "rocketsim",
3
3
  "stageId": "rocketsim-flows",
4
4
  "verificationStages": [
5
- "build",
6
- "unit-tests",
7
- "lint",
8
5
  "rocketsim-flows"
9
6
  ],
10
7
  "stage": {
@@ -19,13 +16,28 @@
19
16
  "kind": "directory",
20
17
  "description": "Screenshots, per-flow results, and run summary"
21
18
  }
22
- ]
19
+ ],
20
+ "tier": "full"
23
21
  },
24
22
  "files": [
25
- { "src": ".har/stages/rocketsim-flows.sh", "dest": ".har/stages/rocketsim-flows.sh", "executable": true },
26
- { "src": ".har/stages/ROCKETSIM.md", "dest": ".har/stages/ROCKETSIM.md" },
27
- { "src": "flows/README.md", "dest": "flows/README.md" },
28
- { "src": "flows/example-smoke.sh", "dest": "flows/example-smoke.sh", "executable": true }
23
+ {
24
+ "src": ".har/stages/rocketsim-flows.sh",
25
+ "dest": ".har/stages/rocketsim-flows.sh",
26
+ "executable": true
27
+ },
28
+ {
29
+ "src": ".har/stages/ROCKETSIM.md",
30
+ "dest": ".har/stages/ROCKETSIM.md"
31
+ },
32
+ {
33
+ "src": "flows/README.md",
34
+ "dest": "flows/README.md"
35
+ },
36
+ {
37
+ "src": "flows/example-smoke.sh",
38
+ "dest": "flows/example-smoke.sh",
39
+ "executable": true
40
+ }
29
41
  ],
30
42
  "nextSteps": [
31
43
  "rocketsim doctor",