feat: [HIMMEL-1640][HIMMEL-1643][HIMMEL-1644][HIMMEL-1645][HIMMEL-1648] leg-6/7 batch: graphify freshness+refresh, arm/suite hardening, critic env pinning - #559
Conversation
…6][HIMMEL-1637][HIMMEL-1287][HIMMEL-1645][HIMMEL-1644][HIMMEL-1648] leg-6/7 batch: graphify freshness+refresh, arm/suite hardening, critic env pinning Batch re-projection of private #1628-#1642 (range 591eebee..c87cee76): - HIMMEL-1640: wire-session-telemetry ownership-by-verb + --off byte-reversibility (#1628), ownedIndex splice guard (#1629), avail supersession identity = (head, model) (#1632), strict frontmatter-ticket parser (both delimiters, hard error on unclosed, line-1 anchored) (#1640) - HIMMEL-1641: GLM worker end conditions - done_escalated terminal state, killed-by-caller finalize, verify-return push-block hint (#1631) - HIMMEL-1643: graphify freshness SessionStart advisory + wire-hook-bash install-when-missing (#1633) - HIMMEL-1646: artifact-critic loads .env credentials like critic-panel (#1634) - HIMMEL-1637: test-arm-resume --only/--list filter + worker-census shield (#1635) - HIMMEL-1606: T_PRUNE_REAL real-arm prune coverage (#1636) - HIMMEL-1287: cmd escapes routed through cadence_cmd_escape; nested-cmd/c proxy site keeps caret escaping (#1637) - HIMMEL-1645: refresh-graph-map GRAPHIFY_API_TIMEOUT knob, 900s ceiling scoped to claude-cli (#1639) - HIMMEL-1644: /graph-refresh one-shot operator refresh + hardened vault preflight (salus/PHI, symlink, configured-identity) (#1641) - HIMMEL-1648: critic credential load_dotenv pinned to script-root resolution, critic-panel + artifact-critic lockstep (#1642) - dependabot minor-and-patch bump (#1638) Platforms tested: windows Security reviewed: ad-hoc
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis PR adds graph refresh tooling, configurable extraction timeouts, worker lifecycle states, credential and ledger updates, handover and hook hardening, telemetry ownership changes, and related tests and documentation. ChangesGraph refresh workflow
GLM worker lifecycle
Critic credentials and availability ledger
Handover arm and test selection
Graph freshness and hook wiring
Session telemetry hook ownership
Package dependency update
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Operator
participant graph-refresh.sh
participant refresh-graph-map.sh
participant graphify
Operator->>graph-refresh.sh: Select corpora and vault
graph-refresh.sh->>refresh-graph-map.sh: Invoke canonical refresh
refresh-graph-map.sh->>graphify: Run graphify --update
graphify-->>refresh-graph-map.sh: Return refresh result
refresh-graph-map.sh-->>graph-refresh.sh: Return corpus result
graph-refresh.sh-->>Operator: Report refresh and cadence status
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (4)
scripts/graphify/test-graph-refresh.sh (2)
374-376: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAssert that the ratified run actually fired the luna leg.
The ratified case checks rc 0 only. rc 0 does not prove the leg ran. Test 15 asserts both rc and the runner log for the same shape. Add the same log assertion here.
♻️ Proposed test strengthening
rc=0; out=$(TEST_LUNA_ROOT="$OTHER_VAULT" run_refresh luna --vault "$OTHER_VAULT" 2>&1) || rc=$? assert_rc "ratified via LUNA_VAULT_PATH -> rc 0" 0 "$rc" +assert_contains "ratified run fired the luna leg" "--name luna" "$(sed -n '1p' "$RUNNER_LOG")" +assert_eq "ratified run fired exactly one leg" "1" "$(wc -l < "$RUNNER_LOG" | tr -d ' ')"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/graphify/test-graph-refresh.sh` around lines 374 - 376, Strengthen the ratified run in test-graph-refresh.sh by adding the same runner-log assertion used by Test 15 after the existing rc 0 check. Verify that the luna leg actually fired, reusing the established log assertion and expected invocation shape.
15-31: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueExtend the
Covers:list to Tests 10-15.The header lists nine cases. The file now runs fifteen, including the preflight cases (salus marker, phi-roots, root/HOME, containment, drive-relative, sentinels, symlink refuse, symlink accept). A reader uses this list as the coverage contract.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/graphify/test-graph-refresh.sh` around lines 15 - 31, Extend the top-level “Covers:” list in the test script from nine entries to fifteen, documenting the preflight cases for salus marker, phi-roots, root/HOME, containment, drive-relative paths, sentinels, symlink refusal, and symlink acceptance. Keep the existing cases unchanged and ensure the list accurately matches all tests executed by the script.scripts/hooks/test-graphify-freshness-advisory.sh (1)
52-55: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winT4 records no result when
rcis non-zero.Line 55 guards the
casewith[ "$rc" -eq 0 ] &&. If the hook exits non-zero, thecasenever runs. The test then calls neitherpassnorfail, so T4 disappears from the counters and the suite still reports success. The other tests (T1, T3a, T3b, T5) always record a result.Split the two assertions like T2 and T3a do.
♻️ Proposed change
-[ "$rc" -eq 0 ] && case "$out" in *absent*|*ABSENT*|*"not trustworthy"*) pass "T4 corrupt reported";; *) fail "T4 corrupt silent: $out";; esac +[ "$rc" -eq 0 ] || fail "T4 corrupt rc=$rc" +case "$out" in *absent*|*ABSENT*|*"not trustworthy"*) pass "T4 corrupt reported";; *) fail "T4 corrupt silent: $out";; esac🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/hooks/test-graphify-freshness-advisory.sh` around lines 52 - 55, Update T4 in the test script to record a result for every hook exit status: separate the return-code assertion from the output-banner case assertion, following the pattern used by T2 and T3a. Ensure a non-zero rc calls fail rather than bypassing both pass and fail, while preserving the existing corrupt-manifest output checks.scripts/hooks/wire-hook-bash.mjs (1)
212-263: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueOptional: anchor the SessionStart array lookup to the
hooksobject.Line 213 takes the first textual match of
/"SessionStart"\s*:\s*\[/anywhere in the file. A"SessionStart"key that appears beforehooks.SessionStart(for example inside another top-level object) would select the wrong span. The downstream re-parse, inventory re-check, and the two security gates make a wrong span fail loudly instead of corrupting the file, so this is a robustness point, not a defect.If you keep the textual approach, consider locating
"hooks"first and searching for"SessionStart"after that index.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/hooks/wire-hook-bash.mjs` around lines 212 - 263, Update installMissingEntries so the SessionStart array lookup is scoped to the hooks object rather than matching the first "SessionStart" key anywhere in the settings text. Locate the hooks object boundary first, then search for the SessionStart array within that scope while preserving the existing missing-key and balance validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.claude/commands/graph-refresh.md:
- Line 33: Update the --vault documentation near the usage examples to state
that the vault must be at or below the resolved luna root, and that an external
vault requires setting LUNA_VAULT_PATH to ratify it. Apply the same
clarification to the corresponding repeated entry.
In `@scripts/cr/artifact-critic.sh`:
- Around line 54-63: Update the case condition in artifact-critic.sh to match
only the explicitly supported Z.ai/GLM model or slug identities, rather than
arbitrary substrings; preserve credential loading for valid lanes and prevent it
for values such as “notglm”. In scripts/cr/test-artifact-critic.sh, add coverage
for a non-GLM model or slug containing “glm” or “zai” and assert that
GLM_API_KEY remains unset.
In `@scripts/graphify/graph-refresh.sh`:
- Around line 301-304: Update the HOME comparison in the preflight check around
_normalize and preflight_refuse to compare trailing-slash-stripped paths
case-insensitively by applying _lc to both home_canon and ap. Preserve the
existing refusal when the normalized vault path equals the operator HOME.
In `@scripts/graphify/test-graph-refresh.sh`:
- Around line 440-452: Update the Test 15 setup around GOOD_REAL/GOOD_LINK to
configure TEST_LUNA_ROOT for the resolved target before invoking run_refresh,
matching the established pattern used by Tests 8 and 12b. Ensure the symlinked
vault remains within the configured luna root so preflight_vault accepts it and
the existing rc=0 and single-leg assertions remain valid.
In `@scripts/handover/arm-resume.sh`:
- Around line 1127-1131: Update the _fm_rc handling in arm-resume so every
nonzero awk status is treated as a fatal frontmatter read/parse failure, while
preserving the existing specific message for status 3. Exit before extracting
_raw or continuing with an empty _fm, ensuring _ho_ticket_strict cannot remain
empty after any awk failure.
- Line 1126: Update the awk program in the frontmatter extraction assignment to
construct the UTF-8 BOM with sprintf("%c%c%c",239,187,191) before processing,
then remove the non-portable \x BOM regex and use the constructed value for the
first-line substitution. Preserve the existing frontmatter parsing and
error-status behavior.
In `@scripts/handover/test-arm-resume.sh`:
- Around line 3695-3696: Replace the non-portable `touch -d '1 day ago'`
invocation for `SIB_RECENT_1606` with a computed timestamp passed to `touch -t`,
preserving the file’s intended age of one day across macOS, Linux, and Windows
Git Bash.
In `@scripts/hooks/graphify-freshness-advisory.sh`:
- Around line 43-45: Validate budget in the hook before invoking
check-graph-freshness.sh: accept only an integer GRAPHIFY_STALENESS_MAX_AGE_DAYS
value and reset invalid or non-integer input to the existing default of 2. Apply
this validation to the budget setup and the corresponding checker invocation
path so invalid configuration remains fail-open and does not populate $out with
usage errors.
In `@scripts/observability/wire-session-telemetry-hooks.mjs`:
- Around line 102-110: Update isWriterCommand and isOurs to recognize only
actual writer invocations using the expected bun or bun run argument form and
the settings-project writer path, rather than any command containing the path
suffix. Preserve verb matching while excluding commands such as echo that merely
contain the writer path and verb as text, and add a regression case covering
that foreign command.
---
Nitpick comments:
In `@scripts/graphify/test-graph-refresh.sh`:
- Around line 374-376: Strengthen the ratified run in test-graph-refresh.sh by
adding the same runner-log assertion used by Test 15 after the existing rc 0
check. Verify that the luna leg actually fired, reusing the established log
assertion and expected invocation shape.
- Around line 15-31: Extend the top-level “Covers:” list in the test script from
nine entries to fifteen, documenting the preflight cases for salus marker,
phi-roots, root/HOME, containment, drive-relative paths, sentinels, symlink
refusal, and symlink acceptance. Keep the existing cases unchanged and ensure
the list accurately matches all tests executed by the script.
In `@scripts/hooks/test-graphify-freshness-advisory.sh`:
- Around line 52-55: Update T4 in the test script to record a result for every
hook exit status: separate the return-code assertion from the output-banner case
assertion, following the pattern used by T2 and T3a. Ensure a non-zero rc calls
fail rather than bypassing both pass and fail, while preserving the existing
corrupt-manifest output checks.
In `@scripts/hooks/wire-hook-bash.mjs`:
- Around line 212-263: Update installMissingEntries so the SessionStart array
lookup is scoped to the hooks object rather than matching the first
"SessionStart" key anywhere in the settings text. Locate the hooks object
boundary first, then search for the SessionStart array within that scope while
preserving the existing missing-key and balance validation.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: e6e8d9e8-3d8f-475b-9faa-dce63dbacfdf
⛔ Files ignored due to path filters (1)
marketplace/plugins/obsidian-triage/tools/package-lock.jsonis excluded by!**/package-lock.json,!**/package-lock.json
📒 Files selected for processing (29)
.claude/commands/graph-refresh.mddocs/commands-catalog.mddocs/glm-offload.mdmarketplace/plugins/obsidian-triage/tools/package.jsonscripts/cr/artifact-critic.shscripts/cr/critic-panel.shscripts/cr/ledger-append.shscripts/cr/test-artifact-critic.shscripts/cr/test-clear-cr-marker.shscripts/cr/test-critic-panel.shscripts/cr/test-ledger-append.shscripts/graphify/graph-refresh.shscripts/graphify/refresh-graph-map.shscripts/graphify/test-graph-refresh.shscripts/graphify/test-refresh-graph-map.shscripts/handover/arm-resume.shscripts/handover/test-arm-resume.shscripts/hooks/graphify-freshness-advisory.shscripts/hooks/test-graphify-freshness-advisory.shscripts/hooks/wire-hook-bash.mjsscripts/hooks/wire-hook-bash.test.mjsscripts/lanes/await-glm-worker.shscripts/lanes/tests/verify-return.test.mjsscripts/lanes/verify-return.mjsscripts/observability/provisioning/alerting/rules.yamlscripts/observability/wire-session-telemetry-hooks.mjsscripts/observability/wire-session-telemetry-hooks.test.mjsscripts/telegram/spawn-glm.test.tsscripts/telegram/spawn-glm.ts
| - `/graph-refresh luna` — refresh only the luna graph. | ||
| - `/graph-refresh himmel` — refresh only the himmel graph. | ||
| - `/graph-refresh both --dry-run` — preview the exact `refresh-graph-map.sh` invocations without running them. | ||
| - `/graph-refresh --vault /path/to/vault` — override the vault root (default: `$LUNA_VAULT_PATH` if set, else `<user-profile>/Documents/luna`). |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Document the configured-root containment rule for --vault.
graph-refresh.sh refuses a luna-leg vault that is not at or under the resolved configured luna root (LUNA_VAULT_PATH, else <home>/Documents/luna). See preflight_vault step (e). The example on Line 33 therefore fails with rc=2 for any path outside that root, which is the common case for an arbitrary /path/to/vault. An operator following this line gets a refusal with no explanation here.
State that a vault outside the configured root must be ratified by setting LUNA_VAULT_PATH.
📝 Proposed doc fix
-- `/graph-refresh --vault /path/to/vault` — override the vault root (default: `$LUNA_VAULT_PATH` if set, else `<user-profile>/Documents/luna`).
+- `/graph-refresh --vault /path/to/vault` — override the vault root (default: `$LUNA_VAULT_PATH` if set, else `<user-profile>/Documents/luna`). On the luna leg the override must resolve at/under the configured luna root; set `LUNA_VAULT_PATH` to ratify a different location.-- `LUNA_VAULT_PATH=<path>` — default vault root when `--vault` is not passed.
+- `LUNA_VAULT_PATH=<path>` — default vault root when `--vault` is not passed, and the configured root the luna leg's `--vault` must sit at/under.Also applies to: 46-46
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.claude/commands/graph-refresh.md at line 33, Update the --vault
documentation near the usage examples to state that the vault must be at or
below the resolved luna root, and that an external vault requires setting
LUNA_VAULT_PATH to ratify it. Apply the same clarification to the corresponding
repeated entry.
| home_canon="$(_normalize "$(_abs "$(resolve_user_home)")")" | ||
| if [ "$ap" = "$home_canon" ]; then | ||
| preflight_refuse "vault is the operator HOME ($ap)" | ||
| fi |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Compare the HOME path case-insensitively.
Every other classification in this preflight lowercases both sides (_under_root calls _lc). This check does a raw string compare. _normalize preserves the drive-letter case, so C:/Users/x and c:/Users/x are unequal here while they name the same directory. On Windows the two forms are both reachable: resolve_user_home returns the cygpath -u form, and --vault can be typed in the drive-rooted form. The HOME refusal then does not fire.
Reuse _lc for both sides, and compare the trailing-slash-stripped forms.
🛡️ Proposed fix
- home_canon="$(_normalize "$(_abs "$(resolve_user_home)")")"
- if [ "$ap" = "$home_canon" ]; then
+ home_canon="$(_lc "$(_normalize "$(_abs "$(resolve_user_home)")")")"
+ if [ "$(_lc "$ap")" = "$home_canon" ]; then
preflight_refuse "vault is the operator HOME ($ap)"
fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| home_canon="$(_normalize "$(_abs "$(resolve_user_home)")")" | |
| if [ "$ap" = "$home_canon" ]; then | |
| preflight_refuse "vault is the operator HOME ($ap)" | |
| fi | |
| home_canon="$(_lc "$(_normalize "$(_abs "$(resolve_user_home)")")")" | |
| if [ "$(_lc "$ap")" = "$home_canon" ]; then | |
| preflight_refuse "vault is the operator HOME ($ap)" | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/graphify/graph-refresh.sh` around lines 301 - 304, Update the HOME
comparison in the preflight check around _normalize and preflight_refuse to
compare trailing-slash-stripped paths case-insensitively by applying _lc to both
home_canon and ap. Preserve the existing refusal when the normalized vault path
equals the operator HOME.
| touch -t 200001010000 "$SIB_STALE_1606" # >7 days old -- must be pruned | ||
| touch -d '1 day ago' "$SIB_RECENT_1606" # 1 day old -- must survive |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Replace touch -d '1 day ago' with a portable form.
touch -d with a relative date string is a GNU coreutils extension. BSD touch on macOS rejects -d '1 day ago', so SIB_RECENT_1606 keeps the current time or the command fails. The suite targets macOS, Linux, and Windows Git Bash.
touch -t with a computed stamp works on all three.
🛠️ Portable timestamp
touch -t 200001010000 "$SIB_STALE_1606" # >7 days old -- must be pruned
-touch -d '1 day ago' "$SIB_RECENT_1606" # 1 day old -- must survive
+# 1 day old -- must survive. `touch -d '1 day ago'` is GNU-only; compute the
+# stamp with python3 (already required by future_time) and pass it to -t.
+touch -t "$(python3 -c 'import datetime;print((datetime.datetime.now()-datetime.timedelta(days=1)).strftime("%Y%m%d%H%M"))')" \
+ "$SIB_RECENT_1606"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| touch -t 200001010000 "$SIB_STALE_1606" # >7 days old -- must be pruned | |
| touch -d '1 day ago' "$SIB_RECENT_1606" # 1 day old -- must survive | |
| touch -t 200001010000 "$SIB_STALE_1606" # >7 days old -- must be pruned | |
| # 1 day old -- must survive. `touch -d '1 day ago'` is GNU-only; compute the | |
| # stamp with python3 (already required by future_time) and pass it to -t. | |
| touch -t "$(python3 -c 'import datetime;print((datetime.datetime.now()-datetime.timedelta(days=1)).strftime("%Y%m%d%H%M"))')" \ | |
| "$SIB_RECENT_1606" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/handover/test-arm-resume.sh` around lines 3695 - 3696, Replace the
non-portable `touch -d '1 day ago'` invocation for `SIB_RECENT_1606` with a
computed timestamp passed to `touch -t`, preserving the file’s intended age of
one day across macOS, Linux, and Windows Git Bash.
Source: Path instructions
| # 2 days = tolerate one missed daily run (pairs with the qmd advisory's 36h | ||
| # philosophy on the checker's day-granular interface). | ||
| budget="${GRAPHIFY_STALENESS_MAX_AGE_DAYS:-2}" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Validate GRAPHIFY_STALENESS_MAX_AGE_DAYS before you pass it to the checker.
check-graph-freshness.sh uses exit code 1 for both "stale" and "usage error". It rejects a non-integer --max-age-days with exit 1. If an operator exports a non-numeric GRAPHIFY_STALENESS_MAX_AGE_DAYS, the hook maps that usage error to state="STALE" and prints the banner in every session, even when the graph is fresh. The checker's usage text also lands in $out.
Validate the budget in the hook and fall back to the default. The hook's own misconfiguration then stays in the fail-open class.
🛠️ Proposed fix
budget="${GRAPHIFY_STALENESS_MAX_AGE_DAYS:-2}"
+case "$budget" in
+ ''|*[!0-9]*) budget=2 ;; # our own bad input -> default, never a false STALE banner
+esacAlso applies to: 60-68
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/hooks/graphify-freshness-advisory.sh` around lines 43 - 45, Validate
budget in the hook before invoking check-graph-freshness.sh: accept only an
integer GRAPHIFY_STALENESS_MAX_AGE_DAYS value and reset invalid or non-integer
input to the existing default of 2. Apply this validation to the budget setup
and the corresponding checker invocation path so invalid configuration remains
fail-open and does not populate $out with usage errors.
…pinned .env registry fixture + ratified symlink-accept vault Cures the shell-unit (ubuntu-latest) red on this PR: the test-critic-panel-registry.sh T1 fixture now plants its .env in a fake himmel root (the HIMMEL-1648 script-root pinning correctly stopped reading the cwd copy), and the test-graph-refresh.sh symlink-ACCEPT case (Linux-only; skips on Windows) ratifies the symlinked vault as the configured root via TEST_LUNA_ROOT per the HIMMEL-1644 r3 containment; the symlink-REFUSE case pins the salus message. No assertion weakened. Private #1643. Platforms tested: windows Security reviewed: ad-hoc
|
@coderabbitai review |
✅ Action performedReview finished.
|
Summary
Leg-6/7 batch re-projection of private #1628–#1642 (private range
591eebee..c87cee76, 15 commits). All changes were CR-cleared privately (critic panel + codex adversarial per PR; findings fixed or premise-verified-and-deferred to tickets); the public re-projection is byte-verified by the ship pipeline.Highlights:
wire-hook-bashinstall-when-missing./graph-refreshone-shot operator refresh with a hardened vault preflight: salus/PHI hard-refuse mirroring the fence classifier, symlink-resolved classification, configured-identity containment (sentinels ≠ identity), canonical-path consumption, drive-relative refusal.GRAPHIFY_API_TIMEOUTknob; the raised 900s ceiling is scoped to the contendingclaude-clibackend only.--offbyte-reversibility; avail supersession identity(head, model); strict frontmatter-ticket parser (both delimiters required, hard parse error on unclosed frontmatter, line-1-anchored opener with BOM strip).test-arm-resume--only/--listsection filter + worker-census shield; real-arm prune coverage.cadence_cmd_escape(nested-cmd/c proxy site keeps caret escaping)..envparity, then both loaders pinned to script-root resolution (lockstep).Tickets: HIMMEL-1640, HIMMEL-1641, HIMMEL-1643, HIMMEL-1646, HIMMEL-1637, HIMMEL-1606, HIMMEL-1287, HIMMEL-1645, HIMMEL-1644, HIMMEL-1648
Summary by CodeRabbit
New Features
Improvements
Bug Fixes