@walwal-harness/cli 6.1.5 → 7.1.0
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.
- package/CHANGELOG.md +12 -0
- package/HR-Resource/academic-academic-anthropologist/SKILL.md +142 -0
- package/HR-Resource/academic-academic-geographer/SKILL.md +144 -0
- package/HR-Resource/academic-academic-historian/SKILL.md +140 -0
- package/HR-Resource/academic-academic-narratologist/SKILL.md +135 -0
- package/HR-Resource/academic-academic-psychologist/SKILL.md +135 -0
- package/HR-Resource/brick-office/SKILL.md +20 -0
- package/HR-Resource/cdo/SKILL.md +33 -0
- package/HR-Resource/ceo/SKILL.md +36 -0
- package/HR-Resource/coo/SKILL.md +36 -0
- package/HR-Resource/cqo/SKILL.md +33 -0
- package/HR-Resource/cto/SKILL.md +36 -0
- package/HR-Resource/design-design-brand-guardian/SKILL.md +339 -0
- package/HR-Resource/design-design-image-prompt-engineer/SKILL.md +253 -0
- package/HR-Resource/design-design-inclusive-visuals-specialist/SKILL.md +88 -0
- package/HR-Resource/design-design-ui-designer/SKILL.md +400 -0
- package/HR-Resource/design-design-ux-architect/SKILL.md +486 -0
- package/HR-Resource/design-design-ux-researcher/SKILL.md +346 -0
- package/HR-Resource/design-design-visual-storyteller/SKILL.md +166 -0
- package/HR-Resource/design-design-whimsy-injector/SKILL.md +455 -0
- package/HR-Resource/engineering-engineering-ai-data-remediation-engineer/SKILL.md +227 -0
- package/HR-Resource/engineering-engineering-ai-engineer/SKILL.md +163 -0
- package/HR-Resource/engineering-engineering-autonomous-optimization-architect/SKILL.md +124 -0
- package/HR-Resource/engineering-engineering-backend-architect/SKILL.md +252 -0
- package/HR-Resource/engineering-engineering-cms-developer/SKILL.md +553 -0
- package/HR-Resource/engineering-engineering-code-reviewer/SKILL.md +93 -0
- package/HR-Resource/engineering-engineering-codebase-onboarding-engineer/SKILL.md +190 -0
- package/HR-Resource/engineering-engineering-data-engineer/SKILL.md +323 -0
- package/HR-Resource/engineering-engineering-database-optimizer/SKILL.md +193 -0
- package/HR-Resource/engineering-engineering-devops-automator/SKILL.md +393 -0
- package/HR-Resource/engineering-engineering-email-intelligence-engineer/SKILL.md +370 -0
- package/HR-Resource/engineering-engineering-embedded-firmware-engineer/SKILL.md +190 -0
- package/HR-Resource/engineering-engineering-feishu-integration-developer/SKILL.md +615 -0
- package/HR-Resource/engineering-engineering-filament-optimization-specialist/SKILL.md +300 -0
- package/HR-Resource/engineering-engineering-frontend-developer/SKILL.md +242 -0
- package/HR-Resource/engineering-engineering-git-workflow-master/SKILL.md +101 -0
- package/HR-Resource/engineering-engineering-incident-response-commander/SKILL.md +461 -0
- package/HR-Resource/engineering-engineering-minimal-change-engineer/SKILL.md +224 -0
- package/HR-Resource/engineering-engineering-mobile-app-builder/SKILL.md +510 -0
- package/HR-Resource/engineering-engineering-rapid-prototyper/SKILL.md +479 -0
- package/HR-Resource/engineering-engineering-security-engineer/SKILL.md +321 -0
- package/HR-Resource/engineering-engineering-senior-developer/SKILL.md +193 -0
- package/HR-Resource/engineering-engineering-software-architect/SKILL.md +98 -0
- package/HR-Resource/engineering-engineering-solidity-smart-contract-engineer/SKILL.md +539 -0
- package/HR-Resource/engineering-engineering-sre/SKILL.md +107 -0
- package/HR-Resource/engineering-engineering-technical-writer/SKILL.md +410 -0
- package/HR-Resource/engineering-engineering-threat-detection-engineer/SKILL.md +551 -0
- package/HR-Resource/engineering-engineering-voice-ai-integration-engineer/SKILL.md +578 -0
- package/HR-Resource/engineering-engineering-wechat-mini-program-developer/SKILL.md +367 -0
- package/HR-Resource/finance-finance-bookkeeper-controller/SKILL.md +277 -0
- package/HR-Resource/finance-finance-financial-analyst/SKILL.md +251 -0
- package/HR-Resource/finance-finance-fpa-analyst/SKILL.md +280 -0
- package/HR-Resource/finance-finance-investment-researcher/SKILL.md +289 -0
- package/HR-Resource/finance-finance-tax-strategist/SKILL.md +256 -0
- package/HR-Resource/game-development-blender-blender-addon-engineer/SKILL.md +251 -0
- package/HR-Resource/game-development-game-audio-engineer/SKILL.md +281 -0
- package/HR-Resource/game-development-game-designer/SKILL.md +184 -0
- package/HR-Resource/game-development-godot-godot-gameplay-scripter/SKILL.md +351 -0
- package/HR-Resource/game-development-godot-godot-multiplayer-engineer/SKILL.md +314 -0
- package/HR-Resource/game-development-godot-godot-shader-developer/SKILL.md +283 -0
- package/HR-Resource/game-development-level-designer/SKILL.md +225 -0
- package/HR-Resource/game-development-narrative-designer/SKILL.md +260 -0
- package/HR-Resource/game-development-roblox-studio-roblox-avatar-creator/SKILL.md +314 -0
- package/HR-Resource/game-development-roblox-studio-roblox-experience-designer/SKILL.md +322 -0
- package/HR-Resource/game-development-roblox-studio-roblox-systems-scripter/SKILL.md +342 -0
- package/HR-Resource/game-development-technical-artist/SKILL.md +246 -0
- package/HR-Resource/game-development-unity-unity-architect/SKILL.md +288 -0
- package/HR-Resource/game-development-unity-unity-editor-tool-developer/SKILL.md +327 -0
- package/HR-Resource/game-development-unity-unity-multiplayer-engineer/SKILL.md +338 -0
- package/HR-Resource/game-development-unity-unity-shader-graph-artist/SKILL.md +286 -0
- package/HR-Resource/game-development-unreal-engine-unreal-multiplayer-architect/SKILL.md +330 -0
- package/HR-Resource/game-development-unreal-engine-unreal-systems-engineer/SKILL.md +327 -0
- package/HR-Resource/game-development-unreal-engine-unreal-technical-artist/SKILL.md +273 -0
- package/HR-Resource/game-development-unreal-engine-unreal-world-builder/SKILL.md +290 -0
- package/HR-Resource/hiring/SKILL.md +28 -0
- package/HR-Resource/index.json +747 -0
- package/HR-Resource/integrations-mcp-memory-backend-architect-with-memory/SKILL.md +264 -0
- package/HR-Resource/marketing-marketing-agentic-search-optimizer/SKILL.md +328 -0
- package/HR-Resource/marketing-marketing-ai-citation-strategist/SKILL.md +187 -0
- package/HR-Resource/marketing-marketing-app-store-optimizer/SKILL.md +338 -0
- package/HR-Resource/marketing-marketing-baidu-seo-specialist/SKILL.md +243 -0
- package/HR-Resource/marketing-marketing-bilibili-content-strategist/SKILL.md +216 -0
- package/HR-Resource/marketing-marketing-book-co-author/SKILL.md +127 -0
- package/HR-Resource/marketing-marketing-carousel-growth-engine/SKILL.md +216 -0
- package/HR-Resource/marketing-marketing-china-ecommerce-operator/SKILL.md +300 -0
- package/HR-Resource/marketing-marketing-china-market-localization-strategist/SKILL.md +300 -0
- package/HR-Resource/marketing-marketing-content-creator/SKILL.md +71 -0
- package/HR-Resource/marketing-marketing-cross-border-ecommerce/SKILL.md +276 -0
- package/HR-Resource/marketing-marketing-douyin-strategist/SKILL.md +166 -0
- package/HR-Resource/marketing-marketing-growth-hacker/SKILL.md +71 -0
- package/HR-Resource/marketing-marketing-instagram-curator/SKILL.md +130 -0
- package/HR-Resource/marketing-marketing-kuaishou-strategist/SKILL.md +240 -0
- package/HR-Resource/marketing-marketing-linkedin-content-creator/SKILL.md +230 -0
- package/HR-Resource/marketing-marketing-livestream-commerce-coach/SKILL.md +322 -0
- package/HR-Resource/marketing-marketing-podcast-strategist/SKILL.md +294 -0
- package/HR-Resource/marketing-marketing-private-domain-operator/SKILL.md +325 -0
- package/HR-Resource/marketing-marketing-reddit-community-builder/SKILL.md +140 -0
- package/HR-Resource/marketing-marketing-seo-specialist/SKILL.md +338 -0
- package/HR-Resource/marketing-marketing-short-video-editing-coach/SKILL.md +429 -0
- package/HR-Resource/marketing-marketing-social-media-strategist/SKILL.md +142 -0
- package/HR-Resource/marketing-marketing-tiktok-strategist/SKILL.md +142 -0
- package/HR-Resource/marketing-marketing-twitter-engager/SKILL.md +143 -0
- package/HR-Resource/marketing-marketing-video-optimization-specialist/SKILL.md +136 -0
- package/HR-Resource/marketing-marketing-wechat-official-account/SKILL.md +162 -0
- package/HR-Resource/marketing-marketing-weibo-strategist/SKILL.md +257 -0
- package/HR-Resource/marketing-marketing-xiaohongshu-specialist/SKILL.md +155 -0
- package/HR-Resource/marketing-marketing-zhihu-strategist/SKILL.md +179 -0
- package/HR-Resource/ops/SKILL.md +46 -0
- package/HR-Resource/paid-media-paid-media-auditor/SKILL.md +88 -0
- package/HR-Resource/paid-media-paid-media-creative-strategist/SKILL.md +88 -0
- package/HR-Resource/paid-media-paid-media-paid-social-strategist/SKILL.md +88 -0
- package/HR-Resource/paid-media-paid-media-ppc-strategist/SKILL.md +88 -0
- package/HR-Resource/paid-media-paid-media-programmatic-buyer/SKILL.md +88 -0
- package/HR-Resource/paid-media-paid-media-search-query-analyst/SKILL.md +88 -0
- package/HR-Resource/paid-media-paid-media-tracking-specialist/SKILL.md +88 -0
- package/HR-Resource/product-product-behavioral-nudge-engine/SKILL.md +97 -0
- package/HR-Resource/product-product-feedback-synthesizer/SKILL.md +136 -0
- package/HR-Resource/product-product-manager/SKILL.md +486 -0
- package/HR-Resource/product-product-sprint-prioritizer/SKILL.md +171 -0
- package/HR-Resource/product-product-trend-researcher/SKILL.md +176 -0
- package/HR-Resource/project-management-project-management-experiment-tracker/SKILL.md +215 -0
- package/HR-Resource/project-management-project-management-jira-workflow-steward/SKILL.md +247 -0
- package/HR-Resource/project-management-project-management-project-shepherd/SKILL.md +211 -0
- package/HR-Resource/project-management-project-management-studio-operations/SKILL.md +217 -0
- package/HR-Resource/project-management-project-management-studio-producer/SKILL.md +220 -0
- package/HR-Resource/project-management-project-manager-senior/SKILL.md +152 -0
- package/HR-Resource/resource-manager/SKILL.md +23 -0
- package/HR-Resource/sales-sales-account-strategist/SKILL.md +244 -0
- package/HR-Resource/sales-sales-coach/SKILL.md +288 -0
- package/HR-Resource/sales-sales-deal-strategist/SKILL.md +197 -0
- package/HR-Resource/sales-sales-discovery-coach/SKILL.md +242 -0
- package/HR-Resource/sales-sales-engineer/SKILL.md +199 -0
- package/HR-Resource/sales-sales-outbound-strategist/SKILL.md +218 -0
- package/HR-Resource/sales-sales-pipeline-analyst/SKILL.md +284 -0
- package/HR-Resource/sales-sales-proposal-strategist/SKILL.md +234 -0
- package/HR-Resource/spatial-computing-macos-spatial-metal-engineer/SKILL.md +354 -0
- package/HR-Resource/spatial-computing-terminal-integration-specialist/SKILL.md +87 -0
- package/HR-Resource/spatial-computing-visionos-spatial-engineer/SKILL.md +71 -0
- package/HR-Resource/spatial-computing-xr-cockpit-interaction-specialist/SKILL.md +49 -0
- package/HR-Resource/spatial-computing-xr-immersive-developer/SKILL.md +49 -0
- package/HR-Resource/spatial-computing-xr-interface-architect/SKILL.md +49 -0
- package/HR-Resource/specialized-accounts-payable-agent/SKILL.md +202 -0
- package/HR-Resource/specialized-agentic-identity-trust/SKILL.md +404 -0
- package/HR-Resource/specialized-agents-orchestrator/SKILL.md +384 -0
- package/HR-Resource/specialized-automation-governance-architect/SKILL.md +233 -0
- package/HR-Resource/specialized-blockchain-security-auditor/SKILL.md +480 -0
- package/HR-Resource/specialized-compliance-auditor/SKILL.md +175 -0
- package/HR-Resource/specialized-corporate-training-designer/SKILL.md +209 -0
- package/HR-Resource/specialized-customer-service/SKILL.md +415 -0
- package/HR-Resource/specialized-data-consolidation-agent/SKILL.md +77 -0
- package/HR-Resource/specialized-government-digital-presales-consultant/SKILL.md +380 -0
- package/HR-Resource/specialized-healthcare-customer-service/SKILL.md +406 -0
- package/HR-Resource/specialized-healthcare-marketing-compliance/SKILL.md +412 -0
- package/HR-Resource/specialized-hospitality-guest-services/SKILL.md +620 -0
- package/HR-Resource/specialized-hr-onboarding/SKILL.md +468 -0
- package/HR-Resource/specialized-identity-graph-operator/SKILL.md +277 -0
- package/HR-Resource/specialized-language-translator/SKILL.md +281 -0
- package/HR-Resource/specialized-legal-billing-time-tracking/SKILL.md +586 -0
- package/HR-Resource/specialized-legal-client-intake/SKILL.md +509 -0
- package/HR-Resource/specialized-legal-document-review/SKILL.md +471 -0
- package/HR-Resource/specialized-loan-officer-assistant/SKILL.md +572 -0
- package/HR-Resource/specialized-lsp-index-engineer/SKILL.md +331 -0
- package/HR-Resource/specialized-real-estate-buyer-seller/SKILL.md +613 -0
- package/HR-Resource/specialized-recruitment-specialist/SKILL.md +526 -0
- package/HR-Resource/specialized-report-distribution-agent/SKILL.md +82 -0
- package/HR-Resource/specialized-retail-customer-returns/SKILL.md +583 -0
- package/HR-Resource/specialized-sales-data-extraction-agent/SKILL.md +84 -0
- package/HR-Resource/specialized-sales-outreach/SKILL.md +442 -0
- package/HR-Resource/specialized-specialized-chief-of-staff/SKILL.md +296 -0
- package/HR-Resource/specialized-specialized-civil-engineer/SKILL.md +373 -0
- package/HR-Resource/specialized-specialized-cultural-intelligence-strategist/SKILL.md +105 -0
- package/HR-Resource/specialized-specialized-developer-advocate/SKILL.md +334 -0
- package/HR-Resource/specialized-specialized-document-generator/SKILL.md +72 -0
- package/HR-Resource/specialized-specialized-french-consulting-market/SKILL.md +209 -0
- package/HR-Resource/specialized-specialized-korean-business-navigator/SKILL.md +233 -0
- package/HR-Resource/specialized-specialized-mcp-builder/SKILL.md +265 -0
- package/HR-Resource/specialized-specialized-model-qa/SKILL.md +505 -0
- package/HR-Resource/specialized-specialized-salesforce-architect/SKILL.md +197 -0
- package/HR-Resource/specialized-specialized-workflow-architect/SKILL.md +614 -0
- package/HR-Resource/specialized-study-abroad-advisor/SKILL.md +299 -0
- package/HR-Resource/specialized-supply-chain-strategist/SKILL.md +599 -0
- package/HR-Resource/specialized-zk-steward/SKILL.md +228 -0
- package/HR-Resource/support-support-analytics-reporter/SKILL.md +382 -0
- package/HR-Resource/support-support-executive-summary-generator/SKILL.md +229 -0
- package/HR-Resource/support-support-finance-tracker/SKILL.md +459 -0
- package/HR-Resource/support-support-infrastructure-maintainer/SKILL.md +635 -0
- package/HR-Resource/support-support-legal-compliance-checker/SKILL.md +605 -0
- package/HR-Resource/support-support-support-responder/SKILL.md +602 -0
- package/HR-Resource/testing-testing-accessibility-auditor/SKILL.md +333 -0
- package/HR-Resource/testing-testing-api-tester/SKILL.md +323 -0
- package/HR-Resource/testing-testing-evidence-collector/SKILL.md +227 -0
- package/HR-Resource/testing-testing-performance-benchmarker/SKILL.md +285 -0
- package/HR-Resource/testing-testing-reality-checker/SKILL.md +253 -0
- package/HR-Resource/testing-testing-test-results-analyzer/SKILL.md +322 -0
- package/HR-Resource/testing-testing-tool-evaluator/SKILL.md +411 -0
- package/HR-Resource/testing-testing-workflow-optimizer/SKILL.md +467 -0
- package/assets/launchd/com.walwal.harness-wake.plist.template +1 -1
- package/assets/templates/company-pipeline-manifest.json +71 -0
- package/assets/templates/config.json +40 -2
- package/bin/init.js +208 -109
- package/commands/goal.md +25 -0
- package/commands/hot-fix.md +25 -0
- package/commands/play-harness.md +22 -0
- package/commands/release-harness.md +22 -0
- package/commands/stop-harness.md +21 -0
- package/conventions/README.md +14 -88
- package/conventions/brick-office.md +5 -0
- package/conventions/cdo.md +6 -0
- package/conventions/ceo.md +9 -0
- package/conventions/coo.md +6 -0
- package/conventions/cqo.md +6 -23
- package/conventions/cto.md +5 -23
- package/conventions/hiring.md +7 -0
- package/conventions/ops.md +9 -0
- package/conventions/resource-manager.md +6 -0
- package/conventions/shared.md +29 -40
- package/gotchas/README.md +14 -82
- package/gotchas/brick-office.md +9 -0
- package/gotchas/cdo.md +9 -0
- package/gotchas/ceo.md +9 -0
- package/gotchas/coo.md +9 -0
- package/gotchas/cqo.md +6 -19
- package/gotchas/cto.md +6 -19
- package/gotchas/hiring.md +9 -0
- package/gotchas/ops.md +17 -0
- package/gotchas/resource-manager.md +9 -0
- package/gotchas/shared.md +13 -0
- package/package.json +11 -17
- package/scripts/conductor-tick.sh +97 -4
- package/scripts/harness-hourly-review.sh +284 -5
- package/scripts/harness-parity-audit.sh +101 -0
- package/scripts/harness-queue-manager.sh +1 -1
- package/scripts/harness-runtime-stop.sh +58 -0
- package/scripts/harness-service-ops-monitor.sh +207 -18
- package/scripts/harness-stop.sh +18 -0
- package/scripts/harness-wake-install.sh +1 -0
- package/scripts/harness-wake.sh +100 -8
- package/scripts/harness-worker-dispatch.sh +52 -21
- package/scripts/harness-worker-evidence-validate.sh +59 -0
- package/scripts/import-agency-agents.js +102 -0
- package/scripts/lib/harness-agent-resolver.sh +127 -0
- package/scripts/play.sh +104 -0
- package/scripts/release.sh +89 -0
- package/conventions/conductor.md +0 -24
- package/conventions/coo-developer.md +0 -24
- package/conventions/dispatcher.md +0 -24
- package/conventions/documentationer.md +0 -24
- package/conventions/evaluator-architecture.md +0 -24
- package/conventions/evaluator-code-quality.md +0 -24
- package/conventions/evaluator-functional.md +0 -24
- package/conventions/evaluator-security.md +0 -24
- package/conventions/evaluator-visual.md +0 -24
- package/conventions/generator-backend.md +0 -24
- package/conventions/generator-designer.md +0 -24
- package/conventions/generator-devops.md +0 -24
- package/conventions/generator-frontend.md +0 -24
- package/conventions/meeting-manager.md +0 -24
- package/conventions/planner.md +0 -24
- package/conventions/service-ops.md +0 -24
- package/gotchas/conductor.md +0 -38
- package/gotchas/coo-developer.md +0 -22
- package/gotchas/dispatcher.md +0 -38
- package/gotchas/documentationer.md +0 -22
- package/gotchas/evaluator-architecture.md +0 -22
- package/gotchas/evaluator-code-quality.md +0 -22
- package/gotchas/evaluator-functional.md +0 -22
- package/gotchas/evaluator-security.md +0 -22
- package/gotchas/evaluator-visual.md +0 -22
- package/gotchas/generator-backend-laravel.md +0 -19
- package/gotchas/generator-backend.md +0 -22
- package/gotchas/generator-designer.md +0 -22
- package/gotchas/generator-devops.md +0 -22
- package/gotchas/generator-frontend.md +0 -22
- package/gotchas/meeting-manager.md +0 -30
- package/gotchas/planner.md +0 -22
- package/gotchas/service-ops.md +0 -30
- package/skills/_shared/dynamic-registration.md +0 -120
- package/skills/brainstorming/SKILL.md +0 -220
- package/skills/brainstorming/references/attribution.md +0 -109
- package/skills/brainstorming/references/spec-document-reviewer-prompt.md +0 -49
- package/skills/brainstorming/references/visual-companion.md +0 -287
- package/skills/brainstorming/scripts/frame-template.html +0 -214
- package/skills/brainstorming/scripts/helper.js +0 -88
- package/skills/brainstorming/scripts/server.cjs +0 -354
- package/skills/brainstorming/scripts/start-server.sh +0 -148
- package/skills/brainstorming/scripts/stop-server.sh +0 -56
- package/skills/conductor/SKILL.md +0 -336
- package/skills/coo-developer/SKILL.md +0 -72
- package/skills/cqo/SKILL.md +0 -146
- package/skills/cto/SKILL.md +0 -141
- package/skills/dispatcher/SKILL.md +0 -298
- package/skills/dispatcher/persona-ceo.md +0 -169
- package/skills/dispatcher/references/convention-flow.md +0 -111
- package/skills/dispatcher/references/gotcha-flow.md +0 -79
- package/skills/dispatcher/references/initialization.md +0 -53
- package/skills/dispatcher/references/pipeline-definitions.md +0 -151
- package/skills/documentationer/SKILL.md +0 -92
- package/skills/evaluator-architecture/SKILL.md +0 -173
- package/skills/evaluator-code-quality/SKILL.md +0 -218
- package/skills/evaluator-code-quality/references/scoring-rubric.md +0 -104
- package/skills/evaluator-functional/SKILL.md +0 -271
- package/skills/evaluator-functional/references/ia-compliance.md +0 -37
- package/skills/evaluator-functional/references/playwright-tools.md +0 -43
- package/skills/evaluator-functional/references/scoring-rubric.md +0 -52
- package/skills/evaluator-security/SKILL.md +0 -172
- package/skills/evaluator-visual/SKILL.md +0 -165
- package/skills/evaluator-visual/references/responsive-checklist.md +0 -44
- package/skills/evaluator-visual/references/scoring-rubric.md +0 -59
- package/skills/generator-backend/SKILL.md +0 -153
- package/skills/generator-backend/references/nestjs-msa-patterns.md +0 -69
- package/skills/generator-backend/references/sprint-contract-be.md +0 -32
- package/skills/generator-designer/SKILL.md +0 -219
- package/skills/generator-devops/SKILL.md +0 -201
- package/skills/generator-frontend/SKILL.md +0 -155
- package/skills/generator-frontend/references/_web-react-legacy/ai-forbidden-patterns.md +0 -89
- package/skills/generator-frontend/references/_web-react-legacy/component-patterns.md +0 -52
- package/skills/generator-frontend/references/_web-react-legacy/design-system-rules.md +0 -139
- package/skills/generator-frontend/references/_web-react-legacy/vercel-best-practices.md +0 -54
- package/skills/meeting-manager/SKILL.md +0 -419
- package/skills/planner/SKILL.md +0 -243
- package/skills/planner/hr-onboard.md +0 -134
- package/skills/planner/hr-recruit.md +0 -99
- package/skills/planner/persona-coo-hr.md +0 -182
- package/skills/planner/references/api-contract-schema.md +0 -34
- package/skills/planner/references/fe-stack-detection.md +0 -164
- package/skills/planner/references/ia-map-guide.md +0 -31
- package/skills/planner/references/plan-template.md +0 -51
- package/skills/service-ops/SKILL.md +0 -295
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# harness-parity-audit.sh — compare installed project company-loop surface to walwal-harness
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
7
|
+
HARNESS_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
8
|
+
MANIFEST="$HARNESS_ROOT/assets/templates/company-pipeline-manifest.json"
|
|
9
|
+
|
|
10
|
+
usage() {
|
|
11
|
+
echo "usage: bash scripts/harness-parity-audit.sh <project-root> [<project-root> ...]" >&2
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
[ "$#" -gt 0 ] || { usage; exit 2; }
|
|
15
|
+
[ -f "$MANIFEST" ] || { echo "MISSING manifest: $MANIFEST" >&2; exit 2; }
|
|
16
|
+
command -v jq >/dev/null 2>&1 || { echo "MISSING jq" >&2; exit 2; }
|
|
17
|
+
|
|
18
|
+
sha() {
|
|
19
|
+
LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 shasum -a 256 "$1" | awk '{print $1}'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
project_path_for() {
|
|
23
|
+
local rel="$1"
|
|
24
|
+
case "$rel" in
|
|
25
|
+
conventions/*) echo ".harness/$rel" ;;
|
|
26
|
+
gotchas/*) echo ".harness/$rel" ;;
|
|
27
|
+
skills/*) echo ".harness/$rel" ;;
|
|
28
|
+
*) echo "$rel" ;;
|
|
29
|
+
esac
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
config_core_filter() {
|
|
33
|
+
jq -S '
|
|
34
|
+
del(.project, .name, .description, .paths, .production, .telegram, .services, .owners, .runtime, .tech_stack, .integrations)
|
|
35
|
+
' "$1"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
status=0
|
|
39
|
+
for project in "$@"; do
|
|
40
|
+
project="$(cd "$project" && pwd)"
|
|
41
|
+
echo "== $project =="
|
|
42
|
+
|
|
43
|
+
if [ ! -d "$project/.harness" ]; then
|
|
44
|
+
echo "DRIFT missing .harness"
|
|
45
|
+
status=1
|
|
46
|
+
continue
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
while IFS= read -r rel; do
|
|
50
|
+
src="$HARNESS_ROOT/$rel"
|
|
51
|
+
dst="$project/$(project_path_for "$rel")"
|
|
52
|
+
if [ ! -f "$src" ]; then
|
|
53
|
+
echo "UPSTREAM_REQUIRED missing-source $rel"
|
|
54
|
+
status=1
|
|
55
|
+
elif [ ! -f "$dst" ]; then
|
|
56
|
+
echo "DRIFT missing $rel -> $(project_path_for "$rel")"
|
|
57
|
+
status=1
|
|
58
|
+
elif [ "$(sha "$src")" != "$(sha "$dst")" ]; then
|
|
59
|
+
echo "DRIFT hash $rel -> $(project_path_for "$rel")"
|
|
60
|
+
status=1
|
|
61
|
+
else
|
|
62
|
+
echo "PASS $rel"
|
|
63
|
+
fi
|
|
64
|
+
done < <(jq -r '.identical_files[]' "$MANIFEST")
|
|
65
|
+
|
|
66
|
+
while IFS=$'\t' read -r src_rel dst_rel mode; do
|
|
67
|
+
src="$HARNESS_ROOT/$src_rel"
|
|
68
|
+
dst="$project/$dst_rel"
|
|
69
|
+
if [ ! -f "$dst" ]; then
|
|
70
|
+
echo "DRIFT missing $dst_rel"
|
|
71
|
+
status=1
|
|
72
|
+
elif [ "$mode" = "identical" ] && [ "$(sha "$src")" != "$(sha "$dst")" ]; then
|
|
73
|
+
echo "DRIFT hash $src_rel -> $dst_rel"
|
|
74
|
+
status=1
|
|
75
|
+
else
|
|
76
|
+
echo "PASS $src_rel -> $dst_rel"
|
|
77
|
+
fi
|
|
78
|
+
done < <(jq -r '.template_mappings[] | [.source, .target, .mode] | @tsv' "$MANIFEST")
|
|
79
|
+
|
|
80
|
+
if [ -f "$project/.harness/config.json" ]; then
|
|
81
|
+
tmp_src="$(mktemp)"
|
|
82
|
+
tmp_dst="$(mktemp)"
|
|
83
|
+
config_core_filter "$HARNESS_ROOT/assets/templates/config.json" > "$tmp_src"
|
|
84
|
+
config_core_filter "$project/.harness/config.json" > "$tmp_dst"
|
|
85
|
+
if jq -e -s '.[0] == .[1]' "$tmp_src" "$tmp_dst" >/dev/null; then
|
|
86
|
+
echo "PASS config-core"
|
|
87
|
+
else
|
|
88
|
+
echo "DRIFT config-core"
|
|
89
|
+
diff -u "$tmp_src" "$tmp_dst" | sed 's/^/ /'
|
|
90
|
+
status=1
|
|
91
|
+
fi
|
|
92
|
+
rm -f "$tmp_src" "$tmp_dst"
|
|
93
|
+
else
|
|
94
|
+
echo "DRIFT missing .harness/config.json"
|
|
95
|
+
status=1
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
echo
|
|
99
|
+
done
|
|
100
|
+
|
|
101
|
+
exit "$status"
|
|
@@ -141,7 +141,7 @@ cmd_init() {
|
|
|
141
141
|
}) | from_entries
|
|
142
142
|
)
|
|
143
143
|
}
|
|
144
|
-
' "$FEATURES" > "$QUEUE"
|
|
144
|
+
' "$FEATURES" > "${QUEUE}.tmp.$$" && mv "${QUEUE}.tmp.$$" "$QUEUE"
|
|
145
145
|
|
|
146
146
|
local ready_count blocked_count passed_count
|
|
147
147
|
ready_count=$(jq '.queue.ready | length' "$QUEUE")
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# harness-runtime-stop.sh — Stop walwal harness play/release runtime mode.
|
|
3
|
+
|
|
4
|
+
set -uo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
7
|
+
source "$SCRIPT_DIR/lib/harness-render-progress.sh"
|
|
8
|
+
|
|
9
|
+
PROJECT_ROOT="$(resolve_harness_root "${HARNESS_PROJECT_ROOT:-.}")" || exit 1
|
|
10
|
+
HARNESS_DIR="$PROJECT_ROOT/.harness"
|
|
11
|
+
PROGRESS="$HARNESS_DIR/progress.json"
|
|
12
|
+
CONFIG="$HARNESS_DIR/config.json"
|
|
13
|
+
RUNTIME_DIR="$HARNESS_DIR/runtime"
|
|
14
|
+
|
|
15
|
+
[ -d "$HARNESS_DIR" ] || { echo "ERROR: .harness/ not found" >&2; exit 1; }
|
|
16
|
+
[ -f "$PROGRESS" ] || { echo "ERROR: .harness/progress.json not found" >&2; exit 1; }
|
|
17
|
+
[ -f "$CONFIG" ] || { echo "ERROR: .harness/config.json not found" >&2; exit 1; }
|
|
18
|
+
command -v jq >/dev/null 2>&1 || { echo "ERROR: jq is required" >&2; exit 1; }
|
|
19
|
+
|
|
20
|
+
MODE_FILE="$RUNTIME_DIR/harness-mode"
|
|
21
|
+
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
22
|
+
stopped=0
|
|
23
|
+
|
|
24
|
+
for pid_file in "$RUNTIME_DIR/play.pid" "$RUNTIME_DIR/release.pid"; do
|
|
25
|
+
[ -f "$pid_file" ] || continue
|
|
26
|
+
pid="$(cat "$pid_file" 2>/dev/null || true)"
|
|
27
|
+
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
|
28
|
+
kill "$pid" 2>/dev/null || true
|
|
29
|
+
sleep 1
|
|
30
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
31
|
+
kill -9 "$pid" 2>/dev/null || true
|
|
32
|
+
fi
|
|
33
|
+
stopped=$((stopped + 1))
|
|
34
|
+
fi
|
|
35
|
+
rm -f "$pid_file"
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
rm -f "$MODE_FILE"
|
|
39
|
+
|
|
40
|
+
tmp_config="$(mktemp)"
|
|
41
|
+
jq '
|
|
42
|
+
.runtime.build.live = false |
|
|
43
|
+
.runtime.production.live = false
|
|
44
|
+
' "$CONFIG" > "$tmp_config" && mv "$tmp_config" "$CONFIG" || rm -f "$tmp_config"
|
|
45
|
+
|
|
46
|
+
tmp="$(mktemp)"
|
|
47
|
+
jq --arg ts "$ts" --arg reason "$*" '
|
|
48
|
+
.runtime_state.mode = "stopped" |
|
|
49
|
+
.runtime_state.stopped_at = $ts |
|
|
50
|
+
.runtime_state.stop_reason = $reason |
|
|
51
|
+
.runtime_state.pid = null |
|
|
52
|
+
.service_ops.requested_mode = null |
|
|
53
|
+
.service_ops.monitor.stream_active = false |
|
|
54
|
+
.runtime.build.live = false |
|
|
55
|
+
.runtime.production.live = false
|
|
56
|
+
' "$PROGRESS" > "$tmp" && mv "$tmp" "$PROGRESS" || rm -f "$tmp"
|
|
57
|
+
|
|
58
|
+
echo "stopped runtime processes: $stopped"
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# harness-service-ops-monitor.sh — deterministic Service-Ops production check
|
|
3
3
|
#
|
|
4
|
-
# Reads .harness/config.json runtime.
|
|
4
|
+
# Reads .env plus .harness/config.json runtime.build.commands[] and
|
|
5
|
+
# runtime.production.services[] and writes:
|
|
5
6
|
# - progress.json.service_ops.health[]
|
|
6
7
|
# - progress.json.service_ops.monitor.last_check
|
|
7
8
|
# - .harness/actions/ops-report-hourly-<timestamp>.md
|
|
@@ -26,6 +27,29 @@ command -v jq >/dev/null 2>&1 || exit 0
|
|
|
26
27
|
|
|
27
28
|
mkdir -p "$ACTIONS_DIR" "$OPS_DIR"
|
|
28
29
|
|
|
30
|
+
ENV_FILE="$PROJECT_ROOT/.env"
|
|
31
|
+
env_base_port=""
|
|
32
|
+
if [ -f "$ENV_FILE" ]; then
|
|
33
|
+
env_base_port="$(grep -E '^HARNESS_BASE_PORT=[0-9]' "$ENV_FILE" 2>/dev/null | tail -1 | cut -d= -f2- | tr -d '"' || true)"
|
|
34
|
+
fi
|
|
35
|
+
config_base_port="$(jq -r 'if .runtime.ports.base == null then "" else (.runtime.ports.base|tostring) end' "$CONFIG" 2>/dev/null || true)"
|
|
36
|
+
base_port="${env_base_port:-$config_base_port}"
|
|
37
|
+
|
|
38
|
+
if [ -z "$base_port" ]; then
|
|
39
|
+
echo "ERROR: HARNESS_BASE_PORT is not set." >&2
|
|
40
|
+
echo "" >&2
|
|
41
|
+
echo " CEO must agree on a {xx}000 base port with the Owner and add it to .env:" >&2
|
|
42
|
+
echo " HARNESS_BASE_PORT=3000" >&2
|
|
43
|
+
echo "" >&2
|
|
44
|
+
echo " OPS cannot monitor ports without a declared base. Set the value and re-run." >&2
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
range_size="$(jq -r '.runtime.ports.range_size // 1000' "$CONFIG" 2>/dev/null || echo 1000)"
|
|
49
|
+
range_max=$((base_port + range_size - 1))
|
|
50
|
+
|
|
51
|
+
build_live=$(jq -r '.runtime.build.live // false' "$CONFIG" 2>/dev/null || echo false)
|
|
52
|
+
build_count=$(jq -r '(.runtime.build.commands // []) | length' "$CONFIG" 2>/dev/null || echo 0)
|
|
29
53
|
live=$(jq -r '.runtime.production.live // false' "$CONFIG" 2>/dev/null || echo false)
|
|
30
54
|
service_count=$(jq -r '(.runtime.production.services // []) | length' "$CONFIG" 2>/dev/null || echo 0)
|
|
31
55
|
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
@@ -74,12 +98,92 @@ log_summary_json() {
|
|
|
74
98
|
'{configured:true, exists:true, path:$path, recent_errors:$errors, last_line:$last}'
|
|
75
99
|
}
|
|
76
100
|
|
|
101
|
+
port_drift() {
|
|
102
|
+
local port="$1"
|
|
103
|
+
if [ -z "$port" ] || [ "$port" = "null" ]; then
|
|
104
|
+
echo "missing"
|
|
105
|
+
elif [ "$port" -lt "$base_port" ] || [ "$port" -gt "$range_max" ]; then
|
|
106
|
+
echo "outside_base_range"
|
|
107
|
+
else
|
|
108
|
+
echo "ok"
|
|
109
|
+
fi
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
build_results_file="$(mktemp)"
|
|
113
|
+
: > "$build_results_file"
|
|
114
|
+
if [ "$build_live" = "true" ] && [ "${build_count:-0}" -gt 0 ]; then
|
|
115
|
+
b=0
|
|
116
|
+
while [ "$b" -lt "$build_count" ]; do
|
|
117
|
+
cmd_cfg="$(jq -c ".runtime.build.commands[$b]" "$CONFIG")"
|
|
118
|
+
name="$(jq -r '.name // ("build-" + (input_line_number|tostring))' <<<"$cmd_cfg")"
|
|
119
|
+
cwd="$(jq -r '.cwd // "."' <<<"$cmd_cfg")"
|
|
120
|
+
command_text="$(jq -r '.command // empty' <<<"$cmd_cfg")"
|
|
121
|
+
expected_port="$(jq -r '.expected_port // empty' <<<"$cmd_cfg")"
|
|
122
|
+
log_path="$(jq -r '.log_path // empty' <<<"$cmd_cfg")"
|
|
123
|
+
owner="$(jq -r '.owner // "cto"' <<<"$cmd_cfg")"
|
|
124
|
+
drift="$(port_drift "$expected_port")"
|
|
125
|
+
|
|
126
|
+
port_state="not_configured"
|
|
127
|
+
if [ -n "$expected_port" ]; then
|
|
128
|
+
if tcp_check "127.0.0.1" "$expected_port"; then port_state="listening"; else port_state="down"; fi
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
log_json="$(log_summary_json "$log_path")"
|
|
132
|
+
status="ok"
|
|
133
|
+
if [ "$drift" != "ok" ]; then
|
|
134
|
+
status="port_drift"
|
|
135
|
+
elif [ -n "$expected_port" ] && [ "$port_state" != "listening" ]; then
|
|
136
|
+
status="down"
|
|
137
|
+
elif [ "$(jq -r '.configured and (.exists|not)' <<<"$log_json")" = "true" ]; then
|
|
138
|
+
status="log_missing"
|
|
139
|
+
elif [ "$(jq -r '.recent_errors // 0' <<<"$log_json")" -gt 0 ]; then
|
|
140
|
+
status="warn"
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
jq -n \
|
|
144
|
+
--arg ts "$ts" \
|
|
145
|
+
--arg name "$name" \
|
|
146
|
+
--arg cwd "$cwd" \
|
|
147
|
+
--arg command "$command_text" \
|
|
148
|
+
--arg expected_port "$expected_port" \
|
|
149
|
+
--arg owner "$owner" \
|
|
150
|
+
--arg port_state "$port_state" \
|
|
151
|
+
--arg port_drift "$drift" \
|
|
152
|
+
--arg status "$status" \
|
|
153
|
+
--argjson log "$log_json" \
|
|
154
|
+
'{
|
|
155
|
+
ts:$ts,
|
|
156
|
+
name:$name,
|
|
157
|
+
cwd:$cwd,
|
|
158
|
+
command:$command,
|
|
159
|
+
expected_port:(if $expected_port == "" or $expected_port == "null" then null else ($expected_port|tonumber?) end),
|
|
160
|
+
owner:$owner,
|
|
161
|
+
port_state:$port_state,
|
|
162
|
+
port_drift:$port_drift,
|
|
163
|
+
log:$log,
|
|
164
|
+
status:$status
|
|
165
|
+
}' >> "$build_results_file"
|
|
166
|
+
b=$((b + 1))
|
|
167
|
+
done
|
|
168
|
+
fi
|
|
169
|
+
build_results_json="$(jq -s '.' "$build_results_file")"
|
|
170
|
+
rm -f "$build_results_file"
|
|
171
|
+
|
|
77
172
|
if [ "$live" != "true" ] || [ "${service_count:-0}" -eq 0 ]; then
|
|
78
|
-
jq --arg ts "$ts" --arg report "$report_rel" '
|
|
173
|
+
jq --arg ts "$ts" --arg report "$report_rel" --argjson build "$build_results_json" '
|
|
79
174
|
.service_ops.monitor.last_check = $ts |
|
|
80
175
|
.service_ops.monitor.stream_active = false |
|
|
81
176
|
.service_ops.monitor.last_report = $report |
|
|
82
|
-
.service_ops.
|
|
177
|
+
.service_ops.build = $build |
|
|
178
|
+
.service_ops.health = [] |
|
|
179
|
+
.service_ops.incident.open = [] |
|
|
180
|
+
.service_ops.incident.signature = "" |
|
|
181
|
+
.service_ops.incident.repeat_count = 0 |
|
|
182
|
+
.service_ops.incident.recovery_required = false |
|
|
183
|
+
.service_ops.incident.partial_recovery = false |
|
|
184
|
+
.service_ops.incident.close_candidate = false |
|
|
185
|
+
.service_ops.incident.closed = false |
|
|
186
|
+
.service_ops.incident.last_seen_at = $ts
|
|
83
187
|
' "$PROGRESS" > "${PROGRESS}.tmp" && mv "${PROGRESS}.tmp" "$PROGRESS"
|
|
84
188
|
|
|
85
189
|
{
|
|
@@ -87,10 +191,24 @@ if [ "$live" != "true" ] || [ "${service_count:-0}" -eq 0 ]; then
|
|
|
87
191
|
echo ""
|
|
88
192
|
echo "- ts: $ts"
|
|
89
193
|
echo "- production.live: $live"
|
|
194
|
+
echo "- build.live: $build_live"
|
|
195
|
+
echo "- base_port: $base_port"
|
|
90
196
|
echo "- services: $service_count"
|
|
197
|
+
echo "- build_commands: $build_count"
|
|
91
198
|
echo "- verdict: NO_PRODUCTION_SERVICES"
|
|
92
199
|
echo ""
|
|
93
|
-
echo "
|
|
200
|
+
echo "## Build Environments"
|
|
201
|
+
echo ""
|
|
202
|
+
echo "| Build | Command | Expected Port | Logs | Status |"
|
|
203
|
+
echo "|---|---|---:|---|---|"
|
|
204
|
+
jq -r '.[] |
|
|
205
|
+
"| \(.name) | `\(.command)` | " +
|
|
206
|
+
((.expected_port // "n/a")|tostring) + " " + .port_state + " " + .port_drift +
|
|
207
|
+
" | " +
|
|
208
|
+
(if (.log.configured|not) then "not configured" elif (.log.exists|not) then "missing" else ((.log.recent_errors|tostring) + " recent errors") end) +
|
|
209
|
+
" | \(.status) |"' <<<"$build_results_json"
|
|
210
|
+
echo ""
|
|
211
|
+
echo "No production service endpoints are configured. Owner+CEO+CTO must define runtime.production.services[] before OPS can monitor live servers."
|
|
94
212
|
} > "$report_path"
|
|
95
213
|
echo "$report_rel"
|
|
96
214
|
exit 0
|
|
@@ -103,14 +221,20 @@ i=0
|
|
|
103
221
|
while [ "$i" -lt "$service_count" ]; do
|
|
104
222
|
svc="$(jq -c ".runtime.production.services[$i]" "$CONFIG")"
|
|
105
223
|
name="$(jq -r '.name // ("service-" + (input_line_number|tostring))' <<<"$svc")"
|
|
224
|
+
environment="$(jq -r '.environment // "unknown"' <<<"$svc")"
|
|
106
225
|
host="$(jq -r '.host // "127.0.0.1"' <<<"$svc")"
|
|
107
226
|
port="$(jq -r '.port // empty' <<<"$svc")"
|
|
108
227
|
health_path="$(jq -r '.health_path // empty' <<<"$svc")"
|
|
109
228
|
expected_status="$(jq -r '.expected_status // 200' <<<"$svc")"
|
|
110
229
|
log_path="$(jq -r '.log_path // empty' <<<"$svc")"
|
|
230
|
+
owner="$(jq -r '.owner // "cto"' <<<"$svc")"
|
|
231
|
+
source="$(jq -r '.source // "owner-provided"' <<<"$svc")"
|
|
232
|
+
drift="$(port_drift "$port")"
|
|
111
233
|
|
|
112
234
|
port_state="unknown"
|
|
113
|
-
if [ -
|
|
235
|
+
if [ -z "$port" ] || [ "$port" = "null" ]; then
|
|
236
|
+
port_state="not_configured"
|
|
237
|
+
elif tcp_check "$host" "$port"; then
|
|
114
238
|
port_state="listening"
|
|
115
239
|
else
|
|
116
240
|
port_state="down"
|
|
@@ -128,7 +252,9 @@ while [ "$i" -lt "$service_count" ]; do
|
|
|
128
252
|
log_json="$(log_summary_json "$log_path")"
|
|
129
253
|
|
|
130
254
|
status="ok"
|
|
131
|
-
if [ "$
|
|
255
|
+
if [ "$drift" != "ok" ]; then
|
|
256
|
+
status="port_drift"
|
|
257
|
+
elif [ "$port_state" != "listening" ]; then
|
|
132
258
|
status="down"
|
|
133
259
|
elif [ "$health_ok" = "false" ]; then
|
|
134
260
|
status="degraded"
|
|
@@ -141,6 +267,7 @@ while [ "$i" -lt "$service_count" ]; do
|
|
|
141
267
|
jq -n \
|
|
142
268
|
--arg ts "$ts" \
|
|
143
269
|
--arg name "$name" \
|
|
270
|
+
--arg environment "$environment" \
|
|
144
271
|
--arg host "$host" \
|
|
145
272
|
--arg port "$port" \
|
|
146
273
|
--arg port_state "$port_state" \
|
|
@@ -150,12 +277,16 @@ while [ "$i" -lt "$service_count" ]; do
|
|
|
150
277
|
--arg health_status "$health_status" \
|
|
151
278
|
--arg health_ok "$health_ok" \
|
|
152
279
|
--arg status "$status" \
|
|
280
|
+
--arg owner "$owner" \
|
|
281
|
+
--arg source "$source" \
|
|
282
|
+
--arg port_drift "$drift" \
|
|
153
283
|
--argjson log "$log_json" \
|
|
154
284
|
'{
|
|
155
285
|
ts:$ts,
|
|
156
286
|
name:$name,
|
|
287
|
+
environment:$environment,
|
|
157
288
|
host:$host,
|
|
158
|
-
port:($port|tonumber?),
|
|
289
|
+
port:(if $port == "" or $port == "null" then null else ($port|tonumber?) end),
|
|
159
290
|
port_state:$port_state,
|
|
160
291
|
health_path:(if $health_path == "" or $health_path == "null" then null else $health_path end),
|
|
161
292
|
health_url:(if $health_url == "" then null else $health_url end),
|
|
@@ -163,6 +294,9 @@ while [ "$i" -lt "$service_count" ]; do
|
|
|
163
294
|
health_status:(if $health_status == "null" then null else ($health_status|tonumber?) end),
|
|
164
295
|
health_ok:(if $health_ok == "true" then true elif $health_ok == "false" then false else null end),
|
|
165
296
|
log:$log,
|
|
297
|
+
owner:$owner,
|
|
298
|
+
source:$source,
|
|
299
|
+
port_drift:$port_drift,
|
|
166
300
|
status:$status
|
|
167
301
|
}' >> "$results_file"
|
|
168
302
|
i=$((i + 1))
|
|
@@ -171,31 +305,65 @@ done
|
|
|
171
305
|
results_json="$(jq -s '.' "$results_file")"
|
|
172
306
|
rm -f "$results_file"
|
|
173
307
|
|
|
174
|
-
down_count="$(jq '[.[] | select(.status == "down" or .status == "degraded")] | length' <<<"$results_json")"
|
|
175
|
-
warn_count="$(jq '[.[] | select(.status == "warn" or .status == "log_missing")] | length' <<<"$results_json")"
|
|
308
|
+
down_count="$(jq '[.[] | select(.status == "down" or .status == "degraded" or (.status == "port_drift" and .port_drift != "missing"))] | length' <<<"$results_json")"
|
|
309
|
+
warn_count="$(jq '[.[] | select(.status == "warn" or .status == "log_missing" or (.status == "port_drift" and .port_drift == "missing"))] | length' <<<"$results_json")"
|
|
176
310
|
ok_count="$(jq '[.[] | select(.status == "ok")] | length' <<<"$results_json")"
|
|
311
|
+
build_warn_count="$(jq '[.[] | select(.status != "ok")] | length' <<<"$build_results_json")"
|
|
177
312
|
verdict="OK"
|
|
178
|
-
if [ "$down_count" -gt 0 ]; then verdict="INCIDENT"; elif [ "$warn_count" -gt 0 ]; then verdict="WARN"; fi
|
|
313
|
+
if [ "$down_count" -gt 0 ]; then verdict="INCIDENT"; elif [ "$warn_count" -gt 0 ] || [ "$build_warn_count" -gt 0 ]; then verdict="WARN"; fi
|
|
179
314
|
|
|
180
315
|
incidents_json="$(jq '
|
|
181
|
-
[ .[] | select(.status == "down" or .status == "degraded") |
|
|
316
|
+
[ .[] | select(.status == "down" or .status == "degraded" or (.status == "port_drift" and .port_drift != "missing")) |
|
|
182
317
|
{
|
|
183
318
|
id: ("OPS-" + (.name | ascii_upcase | gsub("[^A-Z0-9]+";"-"))),
|
|
184
319
|
dept: "Operations",
|
|
185
320
|
severity: (if .status == "down" then "critical" else "high" end),
|
|
186
|
-
message: (.name + " " + .status + " (" + .host + ":" + (.port|tostring) + ")"),
|
|
321
|
+
message: (.name + " " + .status + " (" + .environment + " " + .host + ":" + (.port|tostring) + ")"),
|
|
187
322
|
ts: .ts
|
|
188
323
|
}
|
|
189
324
|
]' <<<"$results_json")"
|
|
325
|
+
incident_signature="$(jq -r '[.[].id] | sort | join(",")' <<<"$incidents_json")"
|
|
326
|
+
prev_signature="$(jq -r '(.service_ops.incident.signature // "") as $s | if $s != "" then $s else ([.service_ops.incident.open[]?.id] | sort | join(",")) end' "$PROGRESS" 2>/dev/null || echo "")"
|
|
327
|
+
prev_repeat="$(jq -r '.service_ops.incident.repeat_count // 0' "$PROGRESS" 2>/dev/null || echo 0)"
|
|
328
|
+
repeat_count=0
|
|
329
|
+
if [ -n "$incident_signature" ]; then
|
|
330
|
+
if [ -n "$prev_signature" ] && [ "${prev_repeat:-0}" -lt 1 ]; then
|
|
331
|
+
prev_repeat=1
|
|
332
|
+
fi
|
|
333
|
+
if [ "$incident_signature" = "$prev_signature" ]; then
|
|
334
|
+
repeat_count=$((prev_repeat + 1))
|
|
335
|
+
else
|
|
336
|
+
repeat_count=1
|
|
337
|
+
fi
|
|
338
|
+
fi
|
|
339
|
+
recovery_required=false
|
|
340
|
+
if [ "$repeat_count" -ge 2 ]; then
|
|
341
|
+
recovery_required=true
|
|
342
|
+
fi
|
|
343
|
+
partial_recovery=false
|
|
344
|
+
close_candidate=false
|
|
345
|
+
if [ "$ok_count" -gt 0 ] && [ "$down_count" -gt 0 ]; then
|
|
346
|
+
partial_recovery=true
|
|
347
|
+
elif [ "$down_count" -eq 0 ] && [ "$warn_count" -eq 0 ]; then
|
|
348
|
+
close_candidate=true
|
|
349
|
+
fi
|
|
190
350
|
|
|
191
|
-
jq --arg ts "$ts" --arg report "$report_rel" --argjson health "$results_json" --argjson incidents "$incidents_json" --argjson warn "$warn_count" --argjson alert "$down_count" '
|
|
351
|
+
jq --arg ts "$ts" --arg report "$report_rel" --arg signature "$incident_signature" --argjson repeat "$repeat_count" --argjson recovery "$recovery_required" --argjson partial "$partial_recovery" --argjson close_candidate "$close_candidate" --argjson build "$build_results_json" --argjson health "$results_json" --argjson incidents "$incidents_json" --argjson warn "$warn_count" --argjson alert "$down_count" '
|
|
192
352
|
.service_ops.monitor.stream_active = false |
|
|
193
353
|
.service_ops.monitor.last_check = $ts |
|
|
194
354
|
.service_ops.monitor.last_report = $report |
|
|
195
355
|
.service_ops.monitor.warns_this_sprint = ((.service_ops.monitor.warns_this_sprint // 0) + $warn) |
|
|
196
356
|
.service_ops.monitor.alerts_this_sprint = ((.service_ops.monitor.alerts_this_sprint // 0) + $alert) |
|
|
357
|
+
.service_ops.build = $build |
|
|
197
358
|
.service_ops.health = $health |
|
|
198
|
-
.service_ops.incident.open = $incidents
|
|
359
|
+
.service_ops.incident.open = $incidents |
|
|
360
|
+
.service_ops.incident.signature = $signature |
|
|
361
|
+
.service_ops.incident.repeat_count = $repeat |
|
|
362
|
+
.service_ops.incident.recovery_required = $recovery |
|
|
363
|
+
.service_ops.incident.partial_recovery = $partial |
|
|
364
|
+
.service_ops.incident.close_candidate = $close_candidate |
|
|
365
|
+
.service_ops.incident.closed = (if $close_candidate then true else false end) |
|
|
366
|
+
.service_ops.incident.last_seen_at = $ts
|
|
199
367
|
' "$PROGRESS" > "${PROGRESS}.tmp" && mv "${PROGRESS}.tmp" "$PROGRESS"
|
|
200
368
|
|
|
201
369
|
{
|
|
@@ -203,16 +371,37 @@ jq --arg ts "$ts" --arg report "$report_rel" --argjson health "$results_json" --
|
|
|
203
371
|
echo ""
|
|
204
372
|
echo "- ts: $ts"
|
|
205
373
|
echo "- production.live: true"
|
|
374
|
+
echo "- build.live: $build_live"
|
|
375
|
+
echo "- base_port: $base_port"
|
|
206
376
|
echo "- services: $service_count"
|
|
377
|
+
echo "- build_commands: $build_count"
|
|
207
378
|
echo "- verdict: $verdict"
|
|
208
379
|
echo "- ok: $ok_count"
|
|
209
380
|
echo "- warnings: $warn_count"
|
|
210
381
|
echo "- alerts: $down_count"
|
|
382
|
+
echo "- incident_signature: ${incident_signature:-none}"
|
|
383
|
+
echo "- repeat_count: $repeat_count"
|
|
384
|
+
echo "- recovery_required: $recovery_required"
|
|
385
|
+
echo "- partial_recovery: $partial_recovery"
|
|
386
|
+
echo "- close_candidate: $close_candidate"
|
|
387
|
+
echo ""
|
|
388
|
+
echo "## Build Environments"
|
|
389
|
+
echo ""
|
|
390
|
+
echo "| Build | Command | Expected Port | Logs | Status |"
|
|
391
|
+
echo "|---|---|---:|---|---|"
|
|
392
|
+
jq -r '.[] |
|
|
393
|
+
"| \(.name) | `\(.command)` | " +
|
|
394
|
+
((.expected_port // "n/a")|tostring) + " " + .port_state + " " + .port_drift +
|
|
395
|
+
" | " +
|
|
396
|
+
(if (.log.configured|not) then "not configured" elif (.log.exists|not) then "missing" else ((.log.recent_errors|tostring) + " recent errors") end) +
|
|
397
|
+
" | \(.status) |"' <<<"$build_results_json"
|
|
398
|
+
echo ""
|
|
399
|
+
echo "## Service Environments"
|
|
211
400
|
echo ""
|
|
212
|
-
echo "| Service | Port | Health | Logs | Status |"
|
|
213
|
-
echo "
|
|
401
|
+
echo "| Service | Env | Port | Health | Logs | Status |"
|
|
402
|
+
echo "|---|---|---:|---|---|---|"
|
|
214
403
|
jq -r '.[] |
|
|
215
|
-
"| \(.name) | \(.host)
|
|
404
|
+
"| \(.name) | \(.environment) | \(.host):" + ((.port // "n/a")|tostring) + " \(.port_state) \(.port_drift) | " +
|
|
216
405
|
(if .health_path == null then "n/a" else ((.health_status // "000")|tostring) + " expected " + ((.expected_status // 200)|tostring) end) +
|
|
217
406
|
" | " +
|
|
218
407
|
(if (.log.configured|not) then "not configured" elif (.log.exists|not) then "missing" else ((.log.recent_errors|tostring) + " recent errors") end) +
|
|
@@ -221,7 +410,7 @@ jq --arg ts "$ts" --arg report "$report_rel" --argjson health "$results_json" --
|
|
|
221
410
|
echo "## Raw"
|
|
222
411
|
echo ""
|
|
223
412
|
echo '```json'
|
|
224
|
-
jq
|
|
413
|
+
jq -n --argjson build "$build_results_json" --argjson services "$results_json" '{build:$build, services:$services}'
|
|
225
414
|
echo '```'
|
|
226
415
|
} > "$report_path"
|
|
227
416
|
|
package/scripts/harness-stop.sh
CHANGED
|
@@ -22,11 +22,29 @@ command -v jq >/dev/null 2>&1 || exit 0
|
|
|
22
22
|
|
|
23
23
|
PROGRESS="$CWD/.harness/progress.json"
|
|
24
24
|
CONFIG="$CWD/.harness/config.json"
|
|
25
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
25
26
|
|
|
26
27
|
# Opt-out
|
|
27
28
|
AUTO_CHAIN=$(jq -r '.behavior.auto_chain_on_stop // true' "$CONFIG" 2>/dev/null || echo "true")
|
|
28
29
|
if [ "$AUTO_CHAIN" != "true" ]; then exit 0; fi
|
|
29
30
|
|
|
31
|
+
# CXX direct-execution guard:
|
|
32
|
+
# If a mission has CXX documents but no worker reports, block the stop so the
|
|
33
|
+
# company loop must hire/dispatch workers instead of ending with CXX-only work.
|
|
34
|
+
if [ -x "$SCRIPT_DIR/harness-worker-evidence-validate.sh" ]; then
|
|
35
|
+
WORKER_EVIDENCE_JSON=$("$SCRIPT_DIR/harness-worker-evidence-validate.sh" "$CWD" json 2>/dev/null || true)
|
|
36
|
+
WORKER_EVIDENCE_OK=$(echo "$WORKER_EVIDENCE_JSON" | jq -r 'if has("ok") then .ok else true end' 2>/dev/null || echo true)
|
|
37
|
+
if [ "$WORKER_EVIDENCE_OK" != "true" ]; then
|
|
38
|
+
REASON=$(echo "$WORKER_EVIDENCE_JSON" | jq -r '
|
|
39
|
+
"CXX 직접 실행 차단: " +
|
|
40
|
+
([.violations[] | "\(.mission) has CXX docs without worker reports: \(.docs | join(","))"] | join("; ")) +
|
|
41
|
+
". harness-hiring/resource-manager로 전문 worker를 고용 또는 배정하고 .harness/documents/{mission}/workers/{worker-name}.md 를 남긴 뒤 계속하라."
|
|
42
|
+
' 2>/dev/null || echo "CXX 직접 실행 차단: worker report가 없는 mission이 있습니다. hired worker 보고서를 먼저 생성하세요.")
|
|
43
|
+
jq -nc --arg reason "$REASON" '{decision:"block", reason:$reason}'
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
fi
|
|
47
|
+
|
|
30
48
|
# 무한루프 방지: 한 sprint 안에서 stop_chain_count 가 상한을 넘으면 중단
|
|
31
49
|
STOP_CHAIN_MAX=$(jq -r '.behavior.auto_chain_max_per_sprint // 200' "$CONFIG" 2>/dev/null || echo 200)
|
|
32
50
|
STOP_CHAIN_COUNT=$(jq -r '.conductor.stop_chain_count // 0' "$PROGRESS" 2>/dev/null || echo 0)
|