heyspex 0.1.0 → 0.2.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.
- package/.claude-plugin/marketplace.json +14 -0
- package/README.md +21 -0
- package/bin/hs.mjs +1089 -104
- package/bin/spexcode.mjs +262 -0
- package/dev-factory/engine/worktree.mjs +740 -0
- package/dev-factory/lib/code-repo-root.mjs +67 -0
- package/dev-factory/lib/context-budget.mjs +84 -0
- package/dev-factory/lib/epic-detect.mjs +190 -0
- package/dev-factory/lib/fleet-queue-file.mjs +846 -0
- package/dev-factory/lib/fleet-queue.mjs +426 -0
- package/dev-factory/lib/fleet-state.mjs +14 -18
- package/dev-factory/lib/model-catalog.mjs +338 -0
- package/dev-factory/lib/seat-context.mjs +199 -0
- package/dev-factory/lib/spec-io.mjs +93 -0
- package/dev-factory/lib/sufficiency-score.mjs +8 -2
- package/dev-factory/lib/worktree-allocator.mjs +744 -0
- package/dev-factory/model-catalog.json +222 -0
- package/dist/cli/hs-check.mjs +1127 -103
- package/dist/cli/hs-claim.mjs +981 -63
- package/dist/cli/hs-connect.mjs +10059 -1729
- package/dist/cli/hs-defer.mjs +5507 -3072
- package/dist/cli/hs-dev.mjs +576 -0
- package/dist/cli/hs-env.mjs +416 -302
- package/dist/cli/hs-index-rebuild.mjs +7334 -0
- package/dist/cli/hs-index-reconcile.mjs +8138 -0
- package/dist/cli/hs-init.mjs +2840 -149
- package/dist/cli/hs-install.mjs +7214 -594
- package/dist/cli/hs-join.mjs +10640 -2421
- package/dist/cli/hs-vault-pull.mjs +8157 -6370
- package/dist/cli/hs-vault-push.mjs +6433 -0
- package/dist/cli/hs-vault.mjs +4029 -1555
- package/dist/cli/hs-workspace.mjs +2702 -538
- package/dist/cli-templates/customer-vault/specs/entity-model.md +594 -601
- package/dist/cli-templates/customer-vault/specs/protocols/canonical-frontmatter-templates.md +110 -177
- package/dist/cli-templates/customer-vault/specs/protocols/destructive-action-checklist.md +122 -0
- package/dist/cli-templates/customer-vault/specs/protocols/memory-protocol.md +13 -15
- package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +91 -0
- package/dist/cli-templates/customer-vault/specs/protocols/spec-hierarchy.md +150 -168
- package/dist/cli-templates/customer-vault/specs/protocols/spec-summary-authoring.md +83 -0
- package/dist/cli-templates/harness-commands/claude/hs-auto.md +36 -0
- package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -0
- package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -0
- package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -0
- package/dist/cli-templates/harness-commands/claude/hs-dev.md +20 -0
- package/dist/cli-templates/harness-commands/claude/hs-doctor.md +32 -0
- package/dist/cli-templates/harness-commands/claude/hs-ground.md +30 -0
- package/dist/cli-templates/harness-commands/claude/hs-handoff.md +33 -0
- package/dist/cli-templates/harness-commands/claude/hs-log.md +27 -0
- package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -0
- package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -0
- package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -0
- package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -0
- package/dist/cli-templates/harness-commands/claude/hs-res.md +63 -0
- package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -0
- package/dist/cli-templates/harness-commands/claude/hs-review.md +23 -0
- package/dist/cli-templates/harness-commands/claude/hs-view.md +28 -0
- package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -0
- package/dist/cli-templates/harness-commands/claude/prototype.md +91 -0
- package/dist/cli-templates/harness-commands/cursor/hs-auto.md +40 -0
- package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +31 -0
- package/dist/cli-templates/harness-commands/cursor/hs-capture.md +65 -0
- package/dist/cli-templates/harness-commands/cursor/hs-defer.md +32 -0
- package/dist/cli-templates/harness-commands/cursor/hs-dev.md +24 -0
- package/dist/cli-templates/harness-commands/cursor/hs-doctor.md +36 -0
- package/dist/cli-templates/harness-commands/cursor/hs-ground.md +33 -0
- package/dist/cli-templates/harness-commands/cursor/hs-handoff.md +37 -0
- package/dist/cli-templates/harness-commands/cursor/hs-log.md +31 -0
- package/dist/cli-templates/harness-commands/cursor/hs-next.md +32 -0
- package/dist/cli-templates/harness-commands/cursor/hs-promote.md +73 -0
- package/dist/cli-templates/harness-commands/cursor/hs-push.md +38 -0
- package/dist/cli-templates/harness-commands/cursor/hs-qc.md +30 -0
- package/dist/cli-templates/harness-commands/cursor/hs-res.md +67 -0
- package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +26 -0
- package/dist/cli-templates/harness-commands/cursor/hs-review.md +26 -0
- package/dist/cli-templates/harness-commands/cursor/hs-view.md +32 -0
- package/dist/cli-templates/harness-commands/cursor/kill-ports.md +35 -0
- package/dist/cli-templates/harness-commands/cursor/prototype.md +95 -0
- package/docs/copilot-plugin-install.md +162 -0
- package/docs/driving-heyspex-from-copilot.md +165 -0
- package/docs/mcp-client-config.md +259 -6
- package/package.json +249 -124
- package/plugins/heyspex/.claude-plugin/plugin.json +12 -0
- package/plugins/heyspex/.cursor-plugin/plugin.json +15 -0
- package/plugins/heyspex/.mcp.json +12 -0
- package/plugins/heyspex/README.md +309 -0
- package/plugins/heyspex/bin/launch-mcp.mjs +95 -0
- package/plugins/heyspex/bin/run-hook.mjs +80 -0
- package/plugins/heyspex/hooks/cursor-hooks.json +308 -0
- package/plugins/heyspex/hooks/hooks.json +418 -0
- package/plugins/heyspex/mcp.json +13 -0
- package/scripts/check-mcp-freshness.mjs +17 -9
- package/scripts/claude-hooks/_env-vault-events.mjs +68 -0
- package/scripts/claude-hooks/_guardrail-events.mjs +96 -0
- package/scripts/claude-hooks/_guardrail-loader.mjs +494 -0
- package/scripts/claude-hooks/_intent-classifier-router.mjs +456 -0
- package/scripts/claude-hooks/_intent-classifier-semantic.mjs +356 -0
- package/scripts/claude-hooks/_run.mjs +413 -0
- package/scripts/claude-hooks/_transcript-text.mjs +60 -0
- package/scripts/claude-hooks/_vault-retrieval.mjs +322 -0
- package/scripts/claude-hooks/agent-spawn-delegation-gate.mjs +133 -0
- package/scripts/claude-hooks/capture-execution-gate.mjs +51 -0
- package/scripts/claude-hooks/capture-workflow-gate.mjs +11 -0
- package/scripts/claude-hooks/check-auto-memory-budget.mjs +396 -0
- package/scripts/claude-hooks/check-claude-md-budget.mjs +327 -0
- package/scripts/claude-hooks/check-mcp-freshness-hook.mjs +14 -0
- package/scripts/claude-hooks/claim-before-code-gate.mjs +11 -0
- package/scripts/claude-hooks/claim-liveness-shared.mjs +577 -0
- package/scripts/claude-hooks/close-terminal-on-ship.mjs +64 -0
- package/scripts/claude-hooks/coo-denylist-gate.mjs +11 -0
- package/scripts/claude-hooks/coo-guard-check.mjs +11 -0
- package/scripts/claude-hooks/deep-research-cost-gate.mjs +11 -0
- package/scripts/claude-hooks/dev-server-task-reminder.mjs +15 -0
- package/scripts/claude-hooks/diagnose-capture-reminder.mjs +11 -0
- package/scripts/claude-hooks/directive-obligation-gate.mjs +11 -0
- package/scripts/claude-hooks/emit-claim-status.mjs +41 -0
- package/scripts/claude-hooks/enforce-session-sequence.mjs +11 -0
- package/scripts/claude-hooks/enforce-vault-naming.mjs +11 -0
- package/scripts/claude-hooks/env-vault-guard.mjs +11 -0
- package/scripts/claude-hooks/epic-milestone-phrasing-gate.mjs +11 -0
- package/scripts/claude-hooks/git-identity-guard.mjs +11 -0
- package/scripts/claude-hooks/git-reflog-audit.mjs +15 -0
- package/scripts/claude-hooks/git-stash-gate.mjs +11 -0
- package/scripts/claude-hooks/guard-auto-memory-writes.mjs +137 -0
- package/scripts/claude-hooks/id-display-format-gate.mjs +11 -0
- package/scripts/claude-hooks/inject-communication-style.mjs +86 -0
- package/scripts/claude-hooks/inject-coo-seat.mjs +78 -0
- package/scripts/claude-hooks/inject-dev-server-awareness.mjs +11 -0
- package/scripts/claude-hooks/inject-doctrine.mjs +13 -0
- package/scripts/claude-hooks/inject-vault-context.mjs +14 -0
- package/scripts/claude-hooks/intent-classifier-trigger.mjs +279 -0
- package/scripts/claude-hooks/log-session-activity.mjs +341 -0
- package/scripts/claude-hooks/naughty-list-gate.mjs +11 -0
- package/scripts/claude-hooks/notify-status-flip.mjs +72 -0
- package/scripts/claude-hooks/plan-exit-ingest-gate.mjs +170 -0
- package/scripts/claude-hooks/plan-ingest-close-reminder.mjs +66 -0
- package/scripts/claude-hooks/plan-review-gate.mjs +11 -0
- package/scripts/claude-hooks/preflight-reminder.mjs +262 -0
- package/scripts/claude-hooks/protected-action-intent.mjs +221 -0
- package/scripts/claude-hooks/research-method-guard.mjs +398 -0
- package/scripts/claude-hooks/research-protocol-gate.mjs +11 -0
- package/scripts/claude-hooks/session-end.mjs +451 -0
- package/scripts/claude-hooks/settings-write-gate.mjs +11 -0
- package/scripts/claude-hooks/settlement-check-gate.mjs +39 -0
- package/scripts/claude-hooks/status-flip-detect.mjs +17 -0
- package/scripts/claude-hooks/terminal-close-shared.mjs +426 -0
- package/scripts/claude-hooks/terminal-close-watcher.mjs +122 -0
- package/scripts/claude-hooks/vault-mirror-catchup.mjs +11 -0
- package/scripts/claude-hooks/vault-write-tier-guard.mjs +11 -0
- package/scripts/claude-hooks/wip-checkpoint.mjs +302 -0
- package/scripts/cursor-hooks/manifest.mjs +281 -0
- package/scripts/dev-server-status.mjs +34 -13
- package/scripts/dev-server-stop.mjs +313 -0
- package/scripts/heyspex-mode.mjs +288 -0
- package/scripts/hs-auto-resolve.mjs +240 -0
- package/scripts/hs-auto-source.mjs +398 -0
- package/scripts/hs-auto.mjs +134 -0
- package/scripts/hs-capture-cli.mjs +326 -0
- package/scripts/hs-classifier.mjs +136 -0
- package/scripts/hs-companion.mjs +88 -0
- package/scripts/hs-gateway.mjs +115 -0
- package/scripts/hs-mode.mjs +125 -0
- package/scripts/hs-next.mjs +441 -0
- package/scripts/hs-settings.mjs +338 -0
- package/scripts/hs-view.mjs +496 -0
- package/scripts/hs-worktree.mjs +201 -0
- package/scripts/install-claude-code-hooks.mjs +272 -0
- package/scripts/install-cursor-hooks.mjs +471 -0
- package/scripts/lib/agent-env-markers.mjs +38 -0
- package/scripts/lib/console-url-resolver.mjs +199 -61
- package/scripts/lib/customer-kit.mjs +1203 -0
- package/scripts/lib/dev-mode.mjs +249 -32
- package/scripts/lib/directive-obligations.mjs +349 -0
- package/scripts/lib/heyspex-home.mjs +72 -0
- package/scripts/lib/hook-dispositions.mjs +210 -0
- package/scripts/lib/hook-vault-header.mjs +30 -0
- package/scripts/lib/hs-command.mjs +277 -0
- package/scripts/lib/hs-companion-settings.mjs +472 -0
- package/scripts/lib/hs-source-branch.mjs +196 -0
- package/scripts/lib/hs-source-commit.mjs +59 -5
- package/scripts/lib/hs-source-identity.mjs +526 -0
- package/scripts/lib/hs-source-log.mjs +13 -22
- package/scripts/lib/hs-source-preflight.mjs +18 -4
- package/scripts/lib/hs-source-push.mjs +386 -307
- package/scripts/lib/hs-worktree-args.mjs +115 -0
- package/scripts/lib/shared-path-helpers.mjs +134 -0
- package/scripts/lib/standalone-doctor.mjs +540 -3
- package/scripts/lib/subagent-git-lock.mjs +109 -0
- package/scripts/lib/template-pin.mjs +34 -0
- package/scripts/lib/window-placement.mjs +109 -0
- package/scripts/provenance-lib.mjs +91 -0
- package/scripts/stamp-provenance-on-edit.mjs +222 -0
- package/scripts/wip-ledger-health.mjs +653 -0
- package/spexharness/doctrine/baseline/SPEXCODE-DOCTRINE.baseline.json +29 -0
- package/spexharness/src/adapters/audit.mjs +197 -0
- package/spexharness/src/adapters/claude-code.mjs +449 -0
- package/spexharness/src/adapters/copilot.mjs +236 -0
- package/spexharness/src/adapters/detect-harness.mjs +34 -0
- package/spexharness/src/chat/tui/ansi.mjs +448 -0
- package/spexharness/src/chat/tui/palette.mjs +22 -0
- package/spexharness/src/chat/tui/select.mjs +208 -0
- package/spexharness/src/config-root.mjs +54 -0
- package/spexharness/src/context-budget.mjs +141 -0
- package/spexharness/src/dev-server-control.mjs +389 -0
- package/spexharness/src/doctrine/behaviour.mjs +371 -0
- package/spexharness/src/doctrine/corpus.mjs +733 -0
- package/spexharness/src/doctrine/inject.mjs +338 -0
- package/spexharness/src/doctrine/merge.mjs +184 -0
- package/spexharness/src/doctrine/sources.mjs +252 -0
- package/spexharness/src/doctrine/synthesize.mjs +401 -0
- package/spexharness/src/doctrine/vault-source.mjs +574 -0
- package/spexharness/src/doctrine/writer.mjs +176 -0
- package/spexharness/src/events.mjs +84 -0
- package/spexharness/src/gates/_shell-write-targets.mjs +77 -0
- package/spexharness/src/gates/capture-workflow-gate.mjs +202 -0
- package/spexharness/src/gates/claim-before-code-gate.decide.mjs +33 -0
- package/spexharness/src/gates/claim-before-code-gate.mjs +129 -0
- package/spexharness/src/gates/deep-research-cost-gate.mjs +275 -0
- package/spexharness/src/gates/diagnose-capture-reminder.mjs +112 -0
- package/spexharness/src/gates/directive-obligation-gate.decide.mjs +132 -0
- package/spexharness/src/gates/directive-obligation-gate.mjs +183 -0
- package/spexharness/src/gates/enforce-session-sequence.mjs +895 -0
- package/spexharness/src/gates/enforce-vault-naming.mjs +215 -0
- package/spexharness/src/gates/epic-milestone-phrasing-gate.mjs +233 -0
- package/spexharness/src/gates/git-identity-guard.decide.mjs +436 -0
- package/spexharness/src/gates/git-identity-guard.mjs +61 -0
- package/spexharness/src/gates/git-reflog-audit.mjs +151 -0
- package/spexharness/src/gates/git-stash-gate.decide.mjs +361 -0
- package/spexharness/src/gates/git-stash-gate.mjs +159 -0
- package/spexharness/src/gates/id-display-format-gate.mjs +190 -0
- package/spexharness/src/gates/inject-doctrine-gate.mjs +89 -0
- package/spexharness/src/gates/inject-vault-context.mjs +239 -0
- package/spexharness/src/gates/naughty-list-gate.mjs +213 -0
- package/spexharness/src/gates/plan-review-gate.mjs +233 -0
- package/spexharness/src/gates/preflight-reminder-gate.mjs +265 -0
- package/spexharness/src/gates/research-protocol-gate.mjs +175 -0
- package/spexharness/src/gates/settings-write-gate.decide.mjs +96 -0
- package/spexharness/src/gates/settings-write-gate.mjs +104 -0
- package/spexharness/src/gates/vault-mirror-catchup.mjs +124 -0
- package/spexharness/src/gates/vault-write-tier-guard.decide.mjs +125 -0
- package/spexharness/src/gates/vault-write-tier-guard.mjs +42 -0
- package/spexharness/src/git-reflog-audit.mjs +294 -0
- package/spexharness/src/intent-classifier.mjs +196 -0
- package/spexharness/src/intent-directive.mjs +626 -0
- package/spexharness/src/profile/learn.mjs +551 -0
- package/spexharness/src/profile/proposals.mjs +357 -0
- package/spexharness/src/profile/vault-inclusion.mjs +386 -0
- package/spexharness/src/redact.mjs +151 -0
- package/spexharness/src/rule-table.mjs +849 -0
- package/spexharness/src/seat-context.mjs +122 -0
- package/spexharness/src/session-bootstrap.mjs +512 -0
- package/spexharness/src/session-record.mjs +815 -0
- package/spexharness/src/token-inventory.mjs +207 -0
- package/vendor/heyspex-mcp/account-switch.mjs +96 -0
- package/vendor/heyspex-mcp/alignment-gate.mjs +315 -1
- package/vendor/heyspex-mcp/blocker-resolver.mjs +37 -2
- package/vendor/heyspex-mcp/breakdown-ladder.mjs +119 -4
- package/vendor/heyspex-mcp/breakdown-source.mjs +271 -0
- package/vendor/heyspex-mcp/breakdown-writer.mjs +23 -3
- package/vendor/heyspex-mcp/capture-buffer-patches.mjs +77 -8
- package/vendor/heyspex-mcp/capture-channel.mjs +55 -5
- package/vendor/heyspex-mcp/capture-console-client.mjs +117 -3
- package/vendor/heyspex-mcp/capture-focus.mjs +1061 -31
- package/vendor/heyspex-mcp/capture-outbox.mjs +15 -5
- package/vendor/heyspex-mcp/capture-sources.mjs +195 -0
- package/vendor/heyspex-mcp/capture-tools.mjs +1264 -0
- package/vendor/heyspex-mcp/claim-tools.mjs +1147 -0
- package/vendor/heyspex-mcp/cli-verbs.mjs +2074 -0
- package/vendor/heyspex-mcp/cli.mjs +207 -15524
- package/vendor/heyspex-mcp/close-branch-report.mjs +102 -0
- package/vendor/heyspex-mcp/cloud-tool-surface.mjs +128 -0
- package/vendor/heyspex-mcp/cloud-vault-writes.mjs +602 -0
- package/vendor/heyspex-mcp/config-seed.yaml +15 -0
- package/vendor/heyspex-mcp/config-settings.mjs +290 -7
- package/vendor/heyspex-mcp/console-fetch.mjs +822 -17
- package/vendor/heyspex-mcp/console-transport.mjs +172 -0
- package/vendor/heyspex-mcp/credentials.mjs +585 -0
- package/vendor/heyspex-mcp/defer-spec.mjs +44 -4
- package/vendor/heyspex-mcp/deferred-reclaim.mjs +29 -3
- package/vendor/heyspex-mcp/design-handlers.mjs +31 -0
- package/vendor/heyspex-mcp/design-tools.mjs +4 -1
- package/vendor/heyspex-mcp/dev-factory-bridge.mjs +4 -4
- package/vendor/heyspex-mcp/dev-mode-core.mjs +45 -0
- package/vendor/heyspex-mcp/dev-tools.mjs +131 -0
- package/vendor/heyspex-mcp/diagnose-handlers.mjs +54 -0
- package/vendor/heyspex-mcp/events-tools.mjs +207 -0
- package/vendor/heyspex-mcp/filing-tools.mjs +723 -0
- package/vendor/heyspex-mcp/fleet-handlers.mjs +37 -0
- package/vendor/heyspex-mcp/fleet-queue-tools.mjs +71 -15
- package/vendor/heyspex-mcp/focus-tools.mjs +190 -0
- package/vendor/heyspex-mcp/folder-trust-store.mjs +60 -0
- package/vendor/heyspex-mcp/http-transport.mjs +302 -0
- package/vendor/heyspex-mcp/list-tools.mjs +257 -0
- package/vendor/heyspex-mcp/login-handoff.mjs +15 -1
- package/vendor/heyspex-mcp/mcp-config.mjs +107 -0
- package/vendor/heyspex-mcp/memory-tools.mjs +523 -0
- package/vendor/heyspex-mcp/mvp-mode.mjs +53 -6
- package/vendor/heyspex-mcp/obligation-backstop.mjs +103 -0
- package/vendor/heyspex-mcp/occupied-keys.mjs +142 -0
- package/vendor/heyspex-mcp/on-deck-brief.mjs +3377 -0
- package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -0
- package/vendor/heyspex-mcp/package-root.mjs +32 -0
- package/vendor/heyspex-mcp/peer-presence.mjs +8 -1
- package/vendor/heyspex-mcp/plan-ground.mjs +621 -652
- package/vendor/heyspex-mcp/plan-push.mjs +908 -22
- package/vendor/heyspex-mcp/plan-review.mjs +124 -30
- package/vendor/heyspex-mcp/preflight-gate.mjs +0 -0
- package/vendor/heyspex-mcp/procedure-handlers.mjs +327 -0
- package/vendor/heyspex-mcp/procedure-tools.mjs +1181 -970
- package/vendor/heyspex-mcp/promote-capture.mjs +388 -69
- package/vendor/heyspex-mcp/promote-diagnose.mjs +74 -0
- package/vendor/heyspex-mcp/promote-research-to-diagnose.mjs +9 -2
- package/vendor/heyspex-mcp/promote-research.mjs +666 -53
- package/vendor/heyspex-mcp/promotion-helpers.mjs +251 -0
- package/vendor/heyspex-mcp/prompts.mjs +1460 -0
- package/vendor/heyspex-mcp/read-path.mjs +191 -15
- package/vendor/heyspex-mcp/receipt-shape.mjs +146 -0
- package/vendor/heyspex-mcp/recipe-handlers.mjs +117 -0
- package/vendor/heyspex-mcp/regen-tasks.mjs +210 -3
- package/vendor/heyspex-mcp/register-spec.mjs +266 -54
- package/vendor/heyspex-mcp/request-context.mjs +83 -0
- package/vendor/heyspex-mcp/research-focus.mjs +207 -4
- package/vendor/heyspex-mcp/research-handlers.mjs +625 -0
- package/vendor/heyspex-mcp/research-tools.mjs +4 -4
- package/vendor/heyspex-mcp/response-budget.mjs +348 -0
- package/vendor/heyspex-mcp/review-focus.mjs +25 -1
- package/vendor/heyspex-mcp/roadmap-default.mjs +70 -0
- package/vendor/heyspex-mcp/search-specs.mjs +280 -0
- package/vendor/heyspex-mcp/seat-block-ledger.mjs +113 -0
- package/vendor/heyspex-mcp/seat-identity.mjs +2 -6
- package/vendor/heyspex-mcp/session-owner.mjs +109 -0
- package/vendor/heyspex-mcp/session-tools.mjs +162 -0
- package/vendor/heyspex-mcp/settings-registry.mjs +232 -0
- package/vendor/heyspex-mcp/settings-tools.mjs +85 -12
- package/vendor/heyspex-mcp/spec-edit-tools.mjs +453 -0
- package/vendor/heyspex-mcp/spec-id-lib.mjs +93 -17
- package/vendor/heyspex-mcp/split-research.mjs +304 -56
- package/vendor/heyspex-mcp/stdio-rpc.mjs +22 -0
- package/vendor/heyspex-mcp/submit-for-review.mjs +150 -7
- package/vendor/heyspex-mcp/summary-contract.mjs +105 -0
- package/vendor/heyspex-mcp/summary-write-tools.mjs +228 -0
- package/vendor/heyspex-mcp/symptom-query.mjs +146 -0
- package/vendor/heyspex-mcp/test-helpers.mjs +123 -1
- package/vendor/heyspex-mcp/tool-catalog.mjs +2819 -0
- package/vendor/heyspex-mcp/tool-dispatch.mjs +657 -0
- package/vendor/heyspex-mcp/tool-helpers.mjs +325 -0
- package/vendor/heyspex-mcp/validate-linkage.mjs +414 -27
- package/vendor/heyspex-mcp/vault-io.mjs +720 -0
- package/vendor/heyspex-mcp/vault-less-endpoints.mjs +52 -0
- package/vendor/heyspex-mcp/vault-resolve.mjs +554 -68
- package/vendor/heyspex-mcp/verify-reproduction.mjs +270 -30
- package/vendor/heyspex-mcp/whoami.mjs +92 -0
- package/vendor/heyspex-mcp/write-outbox.mjs +512 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HeySpex close-out settings registry — the single declaration of every close-out
|
|
3
|
+
* setting: its dotted key, type, shipped default, description, CLI flag, admin-only
|
|
4
|
+
* marker, enforced marker, and which vault templates ship it.
|
|
5
|
+
*
|
|
6
|
+
* WHY: nothing today says which close-out settings exist, so a shipped default has
|
|
7
|
+
* nowhere to live and a mistyped key fails silently ([[HS-FCF5-15XI-RES-user-editable-close-out-settings-with]]).
|
|
8
|
+
* This registry is the one source every face is meant to read — `hs settings`, the
|
|
9
|
+
* MCP settings tools, and (later) the console — instead of each guessing its own
|
|
10
|
+
* fallback.
|
|
11
|
+
*
|
|
12
|
+
* DECLARATION ONLY (HS-6TDH): this module does not read or write
|
|
13
|
+
* `.heyspex/config.yaml`, does not import `config-settings.mjs`, and does not change
|
|
14
|
+
* any existing settings behavior. A later task in the same epic
|
|
15
|
+
* ([[HS-KW38-15XI-EPIC-settings-registry-core]]) teaches `config-settings.mjs` to
|
|
16
|
+
* resolve reads/writes through this registry (defaults, unknown-key refusal,
|
|
17
|
+
* enforced-entry refusal, type/enum validation).
|
|
18
|
+
*
|
|
19
|
+
* DEPENDENCY-FREE: Node stdlib only, no filesystem access at all — same rationale as
|
|
20
|
+
* the sibling module's "DEPENDENCY-FREE" note.
|
|
21
|
+
*
|
|
22
|
+
* Traceability: [[HS-KW38-15XI-EPIC-settings-registry-core]] ·
|
|
23
|
+
* [[HS-FCF5-15XI-RES-user-editable-close-out-settings-with]] ·
|
|
24
|
+
* [[HS-6TDH-15XI-TASK-declare-every-close-out-setting-in-one]]
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {'boolean' | 'string' | 'enum'} SettingType
|
|
29
|
+
*
|
|
30
|
+
* @typedef {Object} SettingEntry
|
|
31
|
+
* @property {string} key - Dotted key, e.g. "close_out.update_docs".
|
|
32
|
+
* @property {SettingType} type - The value's declared type.
|
|
33
|
+
* @property {*} default - The shipped default value (absent-key resolution target).
|
|
34
|
+
* @property {string} description - One or two sentences a person can read as help text.
|
|
35
|
+
* @property {string|null} cliFlag - The `hs close` / `hs settings` flag name (e.g.
|
|
36
|
+
* "--update-docs"), or `null` for an enforced entry with no user-facing flag.
|
|
37
|
+
* @property {boolean} adminOnly - True for a HeySpex-admin-only entry; a non-admin
|
|
38
|
+
* vault must treat the key as unknown.
|
|
39
|
+
* @property {boolean} enforced - True for a hard rule that cannot be changed by
|
|
40
|
+
* anyone through any face, including a HeySpex admin.
|
|
41
|
+
* @property {string[]} templates - Which vault templates ship this entry:
|
|
42
|
+
* "heyspex" (the HeySpex platform vault) and/or "customer" (the shipped customer
|
|
43
|
+
* template).
|
|
44
|
+
* @property {string[]} [values] - Allowed values; present only when `type` is "enum".
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The ordered list of every declared close-out setting. Order is the order the
|
|
49
|
+
* close-out runner is meant to evaluate them in (a later task); it is also the
|
|
50
|
+
* order `hs settings list` should render them in.
|
|
51
|
+
*
|
|
52
|
+
* @type {ReadonlyArray<Readonly<SettingEntry>>}
|
|
53
|
+
*/
|
|
54
|
+
export const SETTINGS_REGISTRY = Object.freeze(
|
|
55
|
+
[
|
|
56
|
+
{
|
|
57
|
+
key: 'close_out.update_docs',
|
|
58
|
+
type: 'boolean',
|
|
59
|
+
default: true,
|
|
60
|
+
description:
|
|
61
|
+
'Updates docs/user and docs/admin per the docs-action rule (create/edit/append) at every close-out.',
|
|
62
|
+
cliFlag: '--update-docs',
|
|
63
|
+
adminOnly: false,
|
|
64
|
+
enforced: false,
|
|
65
|
+
templates: ['heyspex', 'customer'],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
key: 'close_out.review_grain',
|
|
69
|
+
type: 'enum',
|
|
70
|
+
values: ['milestone', 'task'],
|
|
71
|
+
default: 'milestone',
|
|
72
|
+
description:
|
|
73
|
+
'Chooses the close-out review unit: "milestone" flips a completed task straight to closed with no per-task review companion, "task" is the canonical per-task close-out protocol with one HS-REV per task.',
|
|
74
|
+
cliFlag: '--review-grain',
|
|
75
|
+
adminOnly: false,
|
|
76
|
+
enforced: false,
|
|
77
|
+
templates: ['heyspex', 'customer'],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
key: 'close_out.review_backlog_never_blocks',
|
|
81
|
+
type: 'boolean',
|
|
82
|
+
default: true,
|
|
83
|
+
description:
|
|
84
|
+
'A review backlog sitting at in_review/review_pending never blocks a new claim and never needs owner permission.',
|
|
85
|
+
cliFlag: '--review-backlog-never-blocks',
|
|
86
|
+
adminOnly: false,
|
|
87
|
+
enforced: false,
|
|
88
|
+
templates: ['heyspex', 'customer'],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
key: 'close_out.flip_completed_to_closed',
|
|
92
|
+
type: 'boolean',
|
|
93
|
+
default: true,
|
|
94
|
+
description: 'Flips a completed task straight to closed at close-out.',
|
|
95
|
+
cliFlag: '--flip-completed-to-closed',
|
|
96
|
+
adminOnly: false,
|
|
97
|
+
enforced: false,
|
|
98
|
+
templates: ['heyspex', 'customer'],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
key: 'close_out.append_review_seed',
|
|
102
|
+
type: 'boolean',
|
|
103
|
+
default: true,
|
|
104
|
+
description: 'Appends a one-line review seed to the task change-log at close-out.',
|
|
105
|
+
cliFlag: '--append-review-seed',
|
|
106
|
+
adminOnly: false,
|
|
107
|
+
enforced: false,
|
|
108
|
+
templates: ['heyspex', 'customer'],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
key: 'close_out.rolling_review_doc',
|
|
112
|
+
type: 'boolean',
|
|
113
|
+
default: true,
|
|
114
|
+
description: 'Accumulates one rolling review doc per milestone at close-out.',
|
|
115
|
+
cliFlag: '--rolling-review-doc',
|
|
116
|
+
adminOnly: false,
|
|
117
|
+
enforced: false,
|
|
118
|
+
templates: ['heyspex', 'customer'],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
key: 'close_out.run_command_drift_doctor',
|
|
122
|
+
type: 'boolean',
|
|
123
|
+
default: true,
|
|
124
|
+
description:
|
|
125
|
+
'Runs the HeySpex command-drift doctor at close-out. HeySpex-admin-only; a customer vault never sees this key.',
|
|
126
|
+
cliFlag: '--run-command-drift-doctor',
|
|
127
|
+
adminOnly: true,
|
|
128
|
+
enforced: false,
|
|
129
|
+
templates: ['heyspex'],
|
|
130
|
+
},
|
|
131
|
+
// Hard rules: enforced entries cannot be changed by anyone through any face,
|
|
132
|
+
// including a HeySpex admin, so they carry no user-facing CLI flag.
|
|
133
|
+
{
|
|
134
|
+
key: 'close_out.alignment',
|
|
135
|
+
type: 'boolean',
|
|
136
|
+
default: true,
|
|
137
|
+
description: 'Hard rule: alignment stays on. No mode may relax it.',
|
|
138
|
+
cliFlag: null,
|
|
139
|
+
adminOnly: false,
|
|
140
|
+
enforced: true,
|
|
141
|
+
templates: ['heyspex', 'customer'],
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
key: 'close_out.capture',
|
|
145
|
+
type: 'boolean',
|
|
146
|
+
default: true,
|
|
147
|
+
description: 'Hard rule: capture stays on. No mode may relax it.',
|
|
148
|
+
cliFlag: null,
|
|
149
|
+
adminOnly: false,
|
|
150
|
+
enforced: true,
|
|
151
|
+
templates: ['heyspex', 'customer'],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
key: 'close_out.research',
|
|
155
|
+
type: 'boolean',
|
|
156
|
+
default: true,
|
|
157
|
+
description: 'Hard rule: research stays on. No mode may relax it.',
|
|
158
|
+
cliFlag: null,
|
|
159
|
+
adminOnly: false,
|
|
160
|
+
enforced: true,
|
|
161
|
+
templates: ['heyspex', 'customer'],
|
|
162
|
+
},
|
|
163
|
+
// `close_out.git_commit` moved OUT of the hard-rule set above (owner ruling
|
|
164
|
+
// 2026-09-11, [[HS-PROTO-spexsource-agent-protocol]]): whether an agent
|
|
165
|
+
// ever commits at close-out is now a real, permission-gated toggle instead
|
|
166
|
+
// of an unconditional refusal. Default stays `false` for every vault —
|
|
167
|
+
// heyspex and customer alike — so nobody's out-of-box behavior changes; an
|
|
168
|
+
// owner opts in per vault via the normal settings-write-permission flow
|
|
169
|
+
// (`heyspex_settings_set` / `hs settings set --confirmed-by-user`). When
|
|
170
|
+
// `true`, the agent does not commit unconditionally — it still obeys the
|
|
171
|
+
// existing mode logic: the close-out commit lands at the boundary of the
|
|
172
|
+
// *active review grain* (`close_out.review_grain` — task / epic /
|
|
173
|
+
// milestone), routes only through the sanctioned `hs source preflight` →
|
|
174
|
+
// `hs source commit` path, and stays bound by every entry in
|
|
175
|
+
// spexsource-agent-protocol's always-forbidden list (no `--no-verify`, no
|
|
176
|
+
// force, no push — pushing is the separate `close_out.git_push` key,
|
|
177
|
+
// still enforced below). An explicit owner instruction for the session
|
|
178
|
+
// (e.g. "don't commit this one") overrides the setting for that session;
|
|
179
|
+
// the setting only changes the *default* when the owner said nothing.
|
|
180
|
+
{
|
|
181
|
+
key: 'close_out.git_commit',
|
|
182
|
+
type: 'boolean',
|
|
183
|
+
default: false,
|
|
184
|
+
description:
|
|
185
|
+
'Whether the agent commits automatically at close-out. Default false (a dirty tree is the expected hand-off; the human reviewer commits on Pass). When true, the agent still obeys the active review grain (close_out.review_grain) for WHEN to commit and the spexsource-agent-protocol always-forbidden list for HOW — never a bypass of those rules, just an opt-in default.',
|
|
186
|
+
cliFlag: '--git-commit',
|
|
187
|
+
adminOnly: false,
|
|
188
|
+
enforced: false,
|
|
189
|
+
templates: ['heyspex', 'customer'],
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
key: 'close_out.git_push',
|
|
193
|
+
type: 'boolean',
|
|
194
|
+
default: false,
|
|
195
|
+
description: 'Hard rule: an agent never pushes at close-out.',
|
|
196
|
+
cliFlag: null,
|
|
197
|
+
adminOnly: false,
|
|
198
|
+
enforced: true,
|
|
199
|
+
templates: ['heyspex', 'customer'],
|
|
200
|
+
},
|
|
201
|
+
].map((entry) => Object.freeze(entry)),
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
/** Fast key → entry lookup, built once from `SETTINGS_REGISTRY`. */
|
|
205
|
+
const BY_KEY = new Map(SETTINGS_REGISTRY.map((entry) => [entry.key, entry]));
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Look up one registry entry by its dotted key.
|
|
209
|
+
* @param {string} key
|
|
210
|
+
* @returns {Readonly<SettingEntry>|null}
|
|
211
|
+
*/
|
|
212
|
+
export function getSettingEntry(key) {
|
|
213
|
+
if (typeof key !== 'string') return null;
|
|
214
|
+
return BY_KEY.get(key) ?? null;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** True when `key` names a declared registry entry. */
|
|
218
|
+
export function isKnownSetting(key) {
|
|
219
|
+
return getSettingEntry(key) !== null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Every declared key, in registry order. */
|
|
223
|
+
export function listRegistryKeys() {
|
|
224
|
+
return SETTINGS_REGISTRY.map((entry) => entry.key);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Every declared key the given vault template ships ("heyspex" or "customer"). */
|
|
228
|
+
export function listKeysForTemplate(template) {
|
|
229
|
+
return SETTINGS_REGISTRY.filter((entry) => entry.templates.includes(template)).map(
|
|
230
|
+
(entry) => entry.key,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HeySpex settings MCP tools — the agent face over the settings core
|
|
3
|
-
* (config-settings.mjs)
|
|
3
|
+
* (config-settings.mjs) and the settings registry (settings-registry.mjs),
|
|
4
|
+
* mounted in cli.mjs as:
|
|
4
5
|
* - heyspex_settings_list (read — open)
|
|
5
6
|
* - heyspex_settings_get (read — open)
|
|
6
7
|
* - heyspex_settings_set (WRITE — permission-gated two-step confirm)
|
|
7
8
|
*
|
|
9
|
+
* THIRD FACE (HS-OTEQ): these tools resolve every read through
|
|
10
|
+
* `getEffectiveSetting` (file value → registry default → absent) and the
|
|
11
|
+
* registry's key list, and every write through `validateSettingWrite` — the
|
|
12
|
+
* same functions the CLI face (`hs settings`) and, later, the console face
|
|
13
|
+
* resolve through. No fallback of its own: a registry-governed key answers
|
|
14
|
+
* identically no matter which face asks. A key the registry does not declare
|
|
15
|
+
* (e.g. `agent_behaviors.*`, `mvp_mode.*`) keeps working exactly as before —
|
|
16
|
+
* registry entries are additive, never a replacement for the freeform
|
|
17
|
+
* `.heyspex/config.yaml` surface.
|
|
18
|
+
*
|
|
8
19
|
* WRITE-PERMISSION GUARDRAIL (owner directive 2026-07-11, documented in
|
|
9
20
|
* specs/protocols/agent-settings-protocol.md): a settings write is a protected
|
|
10
21
|
* class. `heyspex_settings_set` without `confirm_token` never writes — it records
|
|
@@ -16,31 +27,62 @@
|
|
|
16
27
|
* (scripts/claude-hooks/settings-write-gate.mjs) additionally routes the confirm
|
|
17
28
|
* call through the harness permission prompt in Claude Code.
|
|
18
29
|
*
|
|
30
|
+
* `requestSettingsWrite` (step 1) and `confirmSettingsWrite`/`setConfigLeaf`
|
|
31
|
+
* (step 2) already run every write through `validateSettingWrite` inside the
|
|
32
|
+
* core, so this file does not re-validate — it only shapes the core's
|
|
33
|
+
* `{ ok:false, error, message }` refusal into the tool's response unchanged
|
|
34
|
+
* (never re-worded), which keeps the reason identical to what the CLI face
|
|
35
|
+
* gives for the same refused write.
|
|
36
|
+
*
|
|
19
37
|
* Pattern source: procedure-tools.mjs (pure-logic execute* functions; cli.mjs wraps).
|
|
20
38
|
*/
|
|
21
39
|
|
|
22
40
|
import {
|
|
23
41
|
listConfigLeaves,
|
|
24
|
-
|
|
42
|
+
getEffectiveSetting,
|
|
25
43
|
requestSettingsWrite,
|
|
26
44
|
confirmSettingsWrite,
|
|
27
45
|
validateSettingKey,
|
|
28
46
|
CONFIG_REL,
|
|
29
47
|
} from './config-settings.mjs';
|
|
48
|
+
import { getSettingEntry, listRegistryKeys } from './settings-registry.mjs';
|
|
30
49
|
|
|
31
50
|
const MCP_FACE = 'mcp';
|
|
32
51
|
|
|
52
|
+
/** True when `key` equals `prefix` or is nested under it (dotted-segment match). */
|
|
53
|
+
function matchesPrefix(key, prefix) {
|
|
54
|
+
return !prefix || key === prefix || key.startsWith(prefix + '.');
|
|
55
|
+
}
|
|
56
|
+
|
|
33
57
|
export function executeSettingsList(vaultRoot, args = {}) {
|
|
34
58
|
const prefix = typeof args.prefix === 'string' ? args.prefix.trim() : '';
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
59
|
+
|
|
60
|
+
const fileLeaves = listConfigLeaves(vaultRoot);
|
|
61
|
+
const seen = new Set();
|
|
62
|
+
const settings = [];
|
|
63
|
+
|
|
64
|
+
// Registry-declared keys first, in registry order, resolved through the same
|
|
65
|
+
// file → registry-default chain every face reads through — so a key never
|
|
66
|
+
// written to disk still appears, carrying its shipped default.
|
|
67
|
+
for (const key of listRegistryKeys()) {
|
|
68
|
+
if (!matchesPrefix(key, prefix)) continue;
|
|
69
|
+
const effective = getEffectiveSetting(vaultRoot, key);
|
|
70
|
+
settings.push({ key, value: effective.value, source: effective.source, found: effective.found });
|
|
71
|
+
seen.add(key);
|
|
38
72
|
}
|
|
73
|
+
|
|
74
|
+
// Then any file leaf outside the registry's namespaces (agent_behaviors.*,
|
|
75
|
+
// mvp_mode.*, …) — additive, unchanged from the pre-registry behavior.
|
|
76
|
+
for (const leaf of fileLeaves) {
|
|
77
|
+
if (seen.has(leaf.key) || !matchesPrefix(leaf.key, prefix)) continue;
|
|
78
|
+
settings.push({ key: leaf.key, value: leaf.value, source: 'file', found: true });
|
|
79
|
+
}
|
|
80
|
+
|
|
39
81
|
return {
|
|
40
82
|
ok: true,
|
|
41
83
|
config_file: CONFIG_REL.replace(/\\/g, '/'),
|
|
42
84
|
count: settings.length,
|
|
43
|
-
settings
|
|
85
|
+
settings,
|
|
44
86
|
};
|
|
45
87
|
}
|
|
46
88
|
|
|
@@ -48,13 +90,26 @@ export function executeSettingsGet(vaultRoot, args = {}) {
|
|
|
48
90
|
const key = typeof args.key === 'string' ? args.key.trim() : '';
|
|
49
91
|
const check = validateSettingKey(key);
|
|
50
92
|
if (!check.ok) return { ok: false, error: 'invalid_key', message: check.reason };
|
|
51
|
-
|
|
93
|
+
|
|
94
|
+
const effective = getEffectiveSetting(vaultRoot, key);
|
|
95
|
+
let note;
|
|
96
|
+
if (effective.source === 'registry_default') {
|
|
97
|
+
const entry = getSettingEntry(key);
|
|
98
|
+
note = `Key absent from .heyspex/config.yaml — resolved to the registry default (${entry?.description ?? 'see settings-registry.mjs'}).`;
|
|
99
|
+
} else if (effective.source === 'absent') {
|
|
100
|
+
note = 'Key absent from .heyspex/config.yaml and not declared in the settings registry — consumers fall back to their documented default.';
|
|
101
|
+
} else if (effective.source === 'computed') {
|
|
102
|
+
note =
|
|
103
|
+
'Computed live from the machine-local hs trust store (~/.heyspex/trusted-folders.json) — ' +
|
|
104
|
+
'never read from .heyspex/config.yaml. Read-only: revoke a folder with "hs trust revoke <path>".';
|
|
105
|
+
}
|
|
52
106
|
return {
|
|
53
107
|
ok: true,
|
|
54
108
|
key,
|
|
55
|
-
found:
|
|
56
|
-
value:
|
|
57
|
-
|
|
109
|
+
found: effective.found,
|
|
110
|
+
value: effective.value,
|
|
111
|
+
source: effective.source,
|
|
112
|
+
...(note ? { note } : {}),
|
|
58
113
|
};
|
|
59
114
|
}
|
|
60
115
|
|
|
@@ -81,14 +136,32 @@ export function executeSettingsSet(vaultRoot, args = {}) {
|
|
|
81
136
|
face: MCP_FACE,
|
|
82
137
|
});
|
|
83
138
|
if (!result.ok) return result;
|
|
139
|
+
// MEASURED, NOT ASSUMED ([[HS-IOJW-5YDH-DIAG]] sweep). "applied and audited"
|
|
140
|
+
// used to be printed unconditionally while `appendSettingsAudit`'s boolean
|
|
141
|
+
// was thrown away inside `setConfigLeaf`, so a settings write with no audit
|
|
142
|
+
// row — the one artifact that makes a protected-class write reviewable after
|
|
143
|
+
// the fact — read exactly like a fully audited one. The config write itself
|
|
144
|
+
// DID land, so `ok` stays true and nothing is retried; `audited` + `status`
|
|
145
|
+
// are what let the caller tell a full success from a partial one.
|
|
146
|
+
const audited = result.audited === true;
|
|
84
147
|
return {
|
|
85
148
|
ok: true,
|
|
86
|
-
status: 'applied',
|
|
149
|
+
status: audited ? 'applied' : 'applied_not_audited',
|
|
150
|
+
partial: !audited,
|
|
151
|
+
audited,
|
|
87
152
|
key: result.key,
|
|
88
153
|
previous: result.previous,
|
|
89
154
|
value: result.value,
|
|
90
155
|
created: result.created,
|
|
91
|
-
|
|
156
|
+
// HS-4C76 fix 3: the core seeds a missing config.yaml from the template on
|
|
157
|
+
// the first write instead of refusing; surface that so the caller can say so.
|
|
158
|
+
...(result.seeded === true ? { seeded: true } : {}),
|
|
159
|
+
note: audited
|
|
160
|
+
? `Setting applied and audited to .heyspex/settings-history.jsonl.${result.seeded === true ? ' (.heyspex/config.yaml was missing and was seeded from the template first.)' : ''}`
|
|
161
|
+
: 'Setting APPLIED to .heyspex/config.yaml, but the audit append to ' +
|
|
162
|
+
'.heyspex/settings-history.jsonl FAILED — this write has NO audit row. The value is live; do not ' +
|
|
163
|
+
're-apply it. Tell the user the change is in effect but unaudited, and check that ' +
|
|
164
|
+
'.heyspex/settings-history.jsonl is writable.',
|
|
92
165
|
};
|
|
93
166
|
}
|
|
94
167
|
|