Skip to content

fix(harness): back to opt-in — off unless MEMHUB_HARNESS_EXTRACT is on (v0.76.0) - #270

Merged
felix-xtrace merged 1 commit into
mainfrom
fm-feat/harness-default-off
Sep 21, 2026
Merged

felix-xtrace merged 1 commit into
mainfrom
fm-feat/harness-default-off

Conversation

@felix-xtrace

Copy link
Copy Markdown
Contributor

Ticket: ENG-1107 · Reverts the default from #260

What this decides

#260 (v0.69.0) turned the harness lane on for every install. On costs the person a classifier call per flagged turn and a headless authoring run per moment on their own model quota, and files proposals into a shared team rulebook. Felix's call (2026-09-21): an install should not start that without being asked. Opt-in again — MEMHUB_HARNESS_EXTRACT=1 to turn it on.

What changed

Three gates, flipped together — they are one switch and must never disagree:

  • extract_enabled in harness_extract.py
  • harness_extract_on in rulebook_hook.py (the error-arc pairing)
  • the shell case in claude-hooks.json, which runs before either

The shell gate proceeds only on an explicit on value (1/on/true/yes, any case). Unset, blank and unrecognised all exit before python starts.

Unrecognised values changed sides too, not just the empty string. Under default-on a typo ran the lane; under opt-in a typo must not start the spend. Tests assert both sides, keeping the extra spellings #260 added.

Docs moved in the same change — module headers, the extract_enabled docstring, the rulebook_hook comment, README. Worth noting: the README section was still titled "(flagged off)" and still ended "With the variable unset, the default, none of this runs" — both false since #260, true again with this PR. _OFF is removed; nothing reads it.

Who this affects

Anyone who has been relying on default-on since v0.69.0 (including our own dogfood machines) stops sensing on update unless they set MEMHUB_HARNESS_EXTRACT=1.

Verification

check-plugin.sh 69 of 72, the same three pre-existing failures as origin/main (codex_history, readers_cli, readers_validation). harness_extract_test, harness_stop_test, claude_hook_guard_test all pass.

Nine version files → 0.76.0 (0.74.1 and 0.75.0 are taken by open #268 and #267; whichever merges second rebases its bump).

Not in this PR

The README's harness section still describes the blocking-Stop handoff, while harness_stop.py now authors off-thread. That predates this change and is a separate docs fix.

🤖 Generated with Claude Code

…n (v0.76.0)

#260 (v0.69.0) made the harness lane default-on for every install. On costs
the person a classifier call per flagged turn and a headless authoring run per
moment on THEIR OWN model quota, and files proposals into a shared team
rulebook. Felix's call, 2026-09-21: an install should not start that without
being asked. Opt-in again.

Three gates, flipped together because they are one switch and must never
disagree: `extract_enabled` in harness_extract, `harness_extract_on` in
rulebook_hook (the error-arc pairing), and the shell `case` in
claude-hooks.json that runs before either. The shell gate proceeds only on an
explicit on value (1/on/true/yes, any case), so unset, blank and unrecognised
all exit before python starts.

The empty string moved back with the default, and unrecognised values moved
with it: under default-on a typo ran the lane, under opt-in a typo must not
start the spend. Tests assert both sides, including the spellings #260 added.

Docstrings, the module headers, the rulebook_hook comment and the README moved
in the same change. The README section was still titled "(flagged off)" and
still ended "With the variable unset, the default, none of this runs" — both
false since #260, true again now. `_OFF` is removed; nothing reads it.

Anyone who was relying on default-on since v0.69.0 must now set
MEMHUB_HARNESS_EXTRACT=1.

check-plugin.sh 69 of 72, the same three pre-existing failures as origin/main
(codex_history, readers_cli, readers_validation). Nine version files to 0.76.0
(0.74.1 and 0.75.0 are taken by open #268 and #267).

Refs ENG-1107, reverts the default from #260.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@felix-xtrace
felix-xtrace deployed to production-plugin-release September 21, 2026 19:49 — with GitHub Actions Active
@felix-xtrace
felix-xtrace deployed to production-plugin-release September 21, 2026 19:49 — with GitHub Actions Active
@felix-xtrace
felix-xtrace deployed to production-plugin-release September 21, 2026 19:49 — with GitHub Actions Active
@felix-xtrace
felix-xtrace deployed to production-plugin-release September 21, 2026 19:49 — with GitHub Actions Active

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b35907afc3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

"type": "command",
"timeout": 10,
"command": "IN=$(cat); case \"${MEMHUB_HARNESS_EXTRACT:-}\" in 0|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]|[Nn][Oo]) exit 0 ;; esac; if [ -n \"${CLAUDE_PLUGIN_ROOT:-}\" ] && printf %s \"$IN\" | python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/claude_hook_guard.py\" ignore Stop; then printf %s \"$IN\" | python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/harness_stop.py\" stop; fi"
"command": "IN=$(cat); case \"${MEMHUB_HARNESS_EXTRACT:-}\" in 1|[Oo][Nn]|[Tt][Rr][Uu][Ee]|[Yy][Ee][Ss]) ;; *) exit 0 ;; esac; if [ -n \"${CLAUDE_PLUGIN_ROOT:-}\" ] && printf %s \"$IN\" | python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/claude_hook_guard.py\" ignore Stop; then printf %s \"$IN\" | python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/harness_stop.py\" stop; fi"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize the flag before applying the shell gate

When MEMHUB_HARNESS_EXTRACT contains surrounding whitespace, such as " 1 " or " on ", harness_extract.extract_enabled() strips it and the updated unit test explicitly treats " 1 " as enabled, but this shell case exits before Python runs because it compares the untrimmed value. As a result, a supported enabled value silently leaves the feature disabled when invoked through the actual Stop hook; trim the value here or make the accepted-value semantics consistent across all three gates.

Useful? React with 👍 / 👎.

@felix-xtrace
felix-xtrace merged commit fcdc3b7 into main Sep 21, 2026
12 checks passed
sgonz-xtrace added a commit that referenced this pull request Sep 21, 2026
…-captured

Conflicts resolved:
- extract_enabled / harness_extract_on: keep #270's opt-in parsing
  (explicit on-values only) and put the child gate in front of it.
- The child flag uses the same on-values, as does
  transcript_filter.is_harness_child, so the switch reads one way.
- Version 0.76.0 -> 0.76.1 in all nine version files.

Opt-in makes the child gate matter more, not less: settings.json `env` is
where an install opts in with MEMHUB_HARNESS_EXTRACT=1, and that value
overrides the child's EXTRACT=0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
production-plugin-release — b35907af Deployed Sep 21, 2026 by felix-xtrace via Real agent session (claude candidate) #60
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant