fix(session-flow): root the resume-prompt path and accept both forms on recovery - #1780
Conversation
…on recovery The save-point engine specified the resume directive as `Read @<memory_dir>/handoffs/<TS>-handoff-<topic>.md`, and `memory_dir` is repo-relative by contract — so the one artifact an operator carries across `/clear` lost the root the handoff file was written under. Pasted into a session whose cwd is not the worked-in repository root, the reference resolves somewhere else; when that somewhere else has its own handoffs directory, the failure reads as "the file is missing" rather than "the path has no root". The directive now carries the absolute, forward-slash-normalized path, and a `Handoff origin:` line inside the rails names the repository and repo-relative path so a resume on another machine or checkout can re-resolve. The `@` mention is documented as an accelerator rather than the mechanism: official docs state an `@` path can be relative or absolute but document no drive-letter or whitespace-bearing form, so the directive stays actionable when expansion does not fire. find-handoff inherited the same single-root assumption. Its detection contract now accepts both the rooted and the legacy rootless form, matching on the shape they share and diverging only at the existence check, so the corpus already on disk keeps recovering. A rootless path that resolves to nothing is UNRESOLVED rather than discarded: one bounded read-only widening over repository roots already in hand, then surfaced at the confirm gate with its directive verbatim. Rung 1's repo-correlation check stays open and now says so in place: a handoff file records no durable repository identity, and adding one is a cross-cutting frontmatter schema change decided on its own merits. Refs #1644 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RhS3T7ShwJgKTrvk2Mvd3C
…ked decision The gap statement referenced the defect it was split from rather than the item that carries the decision. #1778 holds the repo-identity frontmatter question with its options; cite that instead. Also makes find-handoff eval 1's cwd-resolution expectation form-aware, so it no longer asserts that every directive path is relative. Refs #1644 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RhS3T7ShwJgKTrvk2Mvd3C
|
Claude finished @kyle-sexton's task in 2m 10s —— View job PR Review —
|
|
Claude finished @kyle-sexton's task in 3m 13s —— View job Security Review — PR #1780
FindingsIMPORTANT · PLAUSIBLE —
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bf8d27ffc5
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…op calling the origin line a signal Review found the rooted path had no not-found rule. `Handoff origin:` was only consulted on the rootless branch — where the contract says it can never appear, since it shipped with the rooted form — so the case it exists for was the one case nothing handled: a resume on a different machine or checkout, where the absolute path is real but local to somewhere else. With no rule, that fell through to discard-on-miss, reintroducing the defect this change removes, one path over. The existence check now branches by path form and converges on one rule. A rooted miss reads the origin line and re-resolves against the repository it names; a rootless miss resolves against the source transcript's cwd as before. Either that lands, or the candidate is UNRESOLVED — and the confirm gate names which failure it was, since "the path has no root" and "nothing is at that absolute path on this machine" send an operator to different places, and "missing" sends them nowhere. `Handoff origin:` is also no longer described as a fourth signal. It cannot admit or reject a candidate, so it was never a detection key, and the label collided with the one the `/loop` re-arm note already holds. It is a resolution input, read after a candidate qualifies, and the signal summary says so instead of listing three signals while the ladder depends on a fourth thing. Adds a rooted-miss eval case, pins the rootless case to its branch explicitly, renames the changelog's non-standard `Known gaps` heading to the precedented `Notes`, and shows a POSIX path beside the Windows one. Refs #1644 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RhS3T7ShwJgKTrvk2Mvd3C
|
Claude finished @kyle-sexton's task in 2m 10s —— View job PR Review —
|
|
Claude finished @kyle-sexton's task in 3m 16s —— View job Security Review — PR #1780
Finding 1 — IMPORTANT · PLAUSIBLE
The prior security review flagged the producer embedding What 6c256ae adds:
Why the redaction pass is insufficient defense here:
The root is in the producer. No instruction to strip the userinfo component before embedding. Recommended fix: In No Further Issues FoundThe following were reviewed and raised no additional security concerns:
|
… before globbing under it `Handoff origin:` embedded the `origin` remote URL verbatim, and an HTTPS remote routinely carries its credential in the URL's userinfo component — a PAT, a stored password, or a credential helper's `x-access-token:<token>@`. The line sits inside the rails, in the region the operator is told to copy, so an embedded secret travels into the next session and onto every machine the prompt reaches. The producer now strips everything from `://` up to and including the `@` before embedding what is left, and falls back to the repository's root directory name when a URL cannot be sanitized with confidence. Both redaction passes name remote URLs as an explicit vector, because a token in a URL reads as one more path segment — the shape a model-driven sweep is likeliest to walk past — and `find-handoff` applies the same check to the value it surfaces at the confirm gate and derives a widening root from, since a recovered handoff predates this rule as easily as it predates the rooted path. The bounded widening globbed a filename under a transcript `cwd` it never verified was a repository root. A session launched straight from a home directory records that home directory as its `cwd`, so the glob recursively walks most of the user's files — the machine-wide scan the rule forbids, reached by accident rather than by intent, and slow enough to time the recovery out. A `cwd` now earns a place in the widening set only once `git -C <cwd> rev-parse --show-toplevel` confirms it, and the search runs under the top level that prints rather than under `cwd` itself. A `cwd` with no top level contributes no root; the candidate stays UNRESOLVED and the operator is asked which checkout to look in. Also: the rooted-miss ladder said "then fall through to the shared rule below", which read as unconditional — the fall-through is now stated as conditional on the origin re-resolution also finding nothing, matching what eval 11 already verified. `<repo-identity>` states the cross-repo case explicitly (name the repository written into, never the one cwd sits in). The handoff eval's scenario path is a portable placeholder rather than a concrete checkout root, which the machine-specific-paths hygiene gate rejects. Evals 12 and 5 cover the widening-root verification and the credential stripping; eval 10's widening expectation is corrected, since its own scenario is the home-directory cwd the rule now refuses to glob under. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 2m 6s —— View job PR Review —
|
| Prior finding | Status |
|---|---|
Security: Handoff origin: embeds raw credential-bearing remote URLs |
Fixed — userinfo stripped at producer; same strip applied in consumer before surfacing/widening |
| Codex P2: widening globs under unverified cwd (home-directory sweep risk) | Fixed — git rev-parse --show-toplevel gate before any glob; home-dir cwd contributes no root |
| Prose: conditional fall-through stated as unconditional | Fixed — "only if that re-resolution ALSO finds nothing" |
Minor: cross-repo cwd ≠ repo case not explicit in <repo-identity> |
Fixed — "when cwd is NOT that repository, name the repository the file was actually written to" |
Verdict
All previously identified findings are resolved. The implementation is correct and internally consistent end-to-end: the producer sanitizes before emitting, the consumer re-sanitizes on recovery for legacy handoffs, the widening is now genuinely bounded to verified repository roots, and the evaluation suite exercises every new branch. Ready to merge.
|
Claude finished @kyle-sexton's task in 2m 47s —— View job Security Review — PR #1780 (latest commit
|
|
Classification of PR Review comment 5126562602 (findings extracted individually; sections 1–5's ✓ affirmations carry no work item).
Pushed as |
|
Classification of Security Review comment 5126563136.
Pushed as |
|
Classification of PR Review comment 5126993370 (the
Pushed as |
|
Classification of Security Review comment 5126996334 (the
Pushed as |
…hecklist The credential-stripping rule lives in the engine spec's `<repo-identity>`, but the checklist item that emits the `Handoff origin:` line is the surface the producer actually ticks. Naming the requirement there — as a qualifier, not a restatement of the rationale — closes the gap where a model satisfies the checklist without reading the engine doc's definition. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 1m 32s —— View job PR Review —
|
|
Claude finished @kyle-sexton's task in 2m 57s —— View job Security Review — PR #1780 (latest commit
|
| Finding | Resolution |
|---|---|
Handoff origin: embeds raw git remote URLs (producer) |
Fixed a9ee2dc — <repo-identity> now requires stripping ://…@ before embedding; redaction pass explicitly names remote URLs as a vector |
find-handoff surfaces Handoff origin: value verbatim at confirm gate |
Fixed a9ee2dc — consumer checks for @ ahead of host and reduces to bare scheme-and-host before surfacing or widening |
Widening globs under unverified cwd (home-directory sweep) |
Fixed a9ee2dc — git -C <cwd> rev-parse --show-toplevel gate before any glob; top-level printed, not cwd itself; home-dir cwd contributes no root |
| Checklist satisfied without reading credential-stripping rule | Fixed ae3a497 — qualifier now in the checklist item itself |
No new security issues found
The following were reviewed against the current branch and raised no concerns:
-
save-point.mdredaction pass — The pass now names git remote URLs explicitly as the shape most likely to evade a generic sweep. The<repo-identity>definition requires userinfo stripping at emit time, making the redaction pass the backstop rather than the mechanism. Belt-and-suspenders is the correct order. ✓ -
find-handoffpath resolution — read-only throughout. The existence check, widening, andgit rev-parsegate are all model-driven reads; no shell command is constructed from transcript-sourced content in a way that introduces injection risk beyond what the model's tool call layer already handles. The candidatecwdgoes to agit -Cflag, not a string-interpolated shell expansion. ✓ -
Handoff origin:as resolution input. The value is sanitized (userinfo stripped) before being surfaced or used to derive a widening root. Legacy handoffs predating the producer fix are handled on the consumer side for exactly this reason. ✓ -
Transcript JSONL scanning. Bounded to
~/.claude/projects/*/, mtime-sorted, capped. Per-candidate decode rather than bulk parse. Role-field pre-filter plus full decode prevents rails in user messages or tool results from qualifying as handoff emissions. ✓ -
Template-placeholder filter. Correctly rejects template tokens without blanket-rejecting angle brackets — preserves
<REDACTED: …>shape markers and valid syntax like<T>. ✓ -
Eval files. New evals (
handofffeat(hook-telemetry): marketplace-wide telemetry contract + markdown-formatter producer #5,find-handofffix(comment-hygiene): exclude '.' from the owner/repo#N leading boundary #12) exercise credential stripping and widening-root verification. No trust-boundary issues in the eval data. ✓ -
Plugin manifest. Semver bump only (
0.17.19→0.17.20). No new config surface, permission grants, or remote MCP endpoints. ✓ -
No GitHub Actions changes. No workflow files modified; supply-chain and dangerous-trigger concerns do not apply. ✓
Verdict
The full PR is clean from a security standpoint. The latest commit closes the one remaining gap — the checklist-vs-engine-spec split on credential stripping — that a prior pass identified as implicit rather than stated. All four previously identified security and correctness findings are resolved. Ready to merge.
|
Follow-up to the two Security Review credential findings (5126563136, 5126996334) — supplementary commit
Verified on the branch: |
…and bound the stripping Two adjacent rules prescribed different outputs for the same secret class with no stated precedence. The general redaction pass says replace a credential with a shape marker and never the value; the git-URL rule two sentences later says strip the userinfo and re-embed the bare scheme-and-host form. A model executing the pass could not tell which governs the `Handoff origin:` value. Both passes now state the precedence and the reason. The URL is reduced to its bare scheme-and-host form and NOT replaced with a marker — a deliberate exception, because the general rule assumes the whole value is secret and unneeded downstream, whereas a remote URL's host and path are non-secret and are exactly what a rooted miss re-resolves from. `<REDACTED: remote URL>` would trade a credential leak for a broken recovery. The stripping rule also gets its boundaries. A bare ssh account name (`ssh://git@host/…`) is not a credential — the secret is the local key the URL does not carry — so it stays; the literal "strip from `://` to `@`" would have dropped it for no gain while misstating the remote. And "cannot be sanitized with confidence" now has a test rather than a vibe: fall back to the root directory name when the userinfo boundary is undeterminable — more than one `@` ahead of the path, or the SCP-style `git@host:<owner>/<repo>.git` form with no `://` to anchor stripping on. `<repo-identity>`'s summary sentence named only two outcomes and now names the sanitization condition as well. Eval 5's expectations are tightened to the credential-bearing userinfo and assert the bare-host form over a shape marker; eval 6 covers the ssh and SCP-form branches. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 1m 44s —— View job PR Review —
|
| Prior finding | Status |
|---|---|
Rule conflict: general redaction (shape marker) vs. git-URL rule (strip-and-keep) — ambiguous precedence for Handoff origin: |
Fixed — git-URL rule is explicitly named the winner with stated rationale; mirrors in both producer and consumer |
Credential-bearing remote URLs embedded in Handoff origin: |
Closed in prior commit; unchanged |
Widening globs under unverified cwd |
Closed in prior commit; unchanged |
| Conditional fall-through stated as unconditional | Closed in prior commit; unchanged |
Verdict
The commit correctly resolves the precedence ambiguity without disturbing any of the prior fixes. The SSH account name exception and the SCP-style fallback are correctly reasoned, the test for "undeterminable boundary" is concrete, and the eval set covers both new branches. Ready to merge.
|
Claude finished @kyle-sexton's task in 4m 15s —— View job Security Review — PR #1780 (latest commit
|
| Finding | Resolution |
|---|---|
Handoff origin: embedded raw credential-bearing git remote URLs |
Fixed a9ee2dc |
| Widening globbed under unverified cwd (home-directory sweep) | Fixed a9ee2dc |
| Checklist satisfied without reading credential-stripping rule | Fixed ae3a497 |
| Two rules prescribed different outputs for the same secret class, no precedence stated | Fixed 001808c |
One new SUGGESTION — 001808c
Severity: SUGGESTION — Confidence: LOW
"Any URL in the outbound set" scope is slightly broader than the intended git-remote-only exception.
So any URL in the outbound set is checked for an
@ahead of its host. Drop the userinfo and keep the rest — do NOT replace the URL with a shape marker. This is a deliberate exception to the rule above, and for this one class it wins.
The phrase "any URL in the outbound set" sits in a paragraph scoped to git remote URLs and "this one class" correctly limits the exception. However, a model parsing this literally could apply the strip-and-preserve treatment to any credential-bearing URL it finds anywhere in the handoff body — not just a git remote URL in the Handoff origin: line. For example, a database connection string like mongodb+srv://admin:secret@prod-db.internal/mydb would, under this reading, emit as mongodb+srv://prod-db.internal/mydb rather than <REDACTED: database connection string>. The userinfo credential is removed in both interpretations, so there is no credential leak risk; but the host and path remain visible where the general rule would have redacted them, which is a minor infrastructure-disclosure difference.
The intent is clear from context — the paragraph starts with "Git remote URLs are a named vector", and <repo-identity> separately constrains what appears in Handoff origin: to git remote URLs. But "any git remote URL in the outbound set" would make the scope unambiguous and prevent the parse that applies the strip-and-keep treatment to non-git URLs.
Confidence is LOW because a well-trained model reads contextually (the whole paragraph is about git remote URLs) and because even the worst-case reading still removes the credential. The risk is an information-leak of infrastructure host names, not a credential leak.
No new issues found on other surfaces
- SSH carve-out is correct.
ssh://git@host/…retainsgit@safely — no credential is in a Git SSH URL; the authentication secret is the local private key, which the URL does not contain. Dropping the account name would misstate the remote without improving security. - SCP-style and multi-
@fallback is safe. Falling back to the root directory name rather than guessing where userinfo ends is the conservative path — it loses URL-based recovery identity, not the secret. - Consumer-side rule (
find-handoff/SKILL.mdlines 344–358) is correctly scoped to "theHandoff origin:value" rather than all URLs, so the scope ambiguity noted above does not appear on the consumer side. - No GitHub Actions changes. No workflow files modified; supply-chain and dangerous-trigger concerns do not apply.
- Plugin manifest. Semver bump only; no new config surface, permission grants, or remote MCP endpoints.
- Eval 6 covers both branches (SSH stays, SCP falls back) correctly and without trust-boundary issues in the eval data itself.
Verdict
The PR is clean from a security standpoint. The latest commit correctly resolves the rule-precedence ambiguity and tightens the stripping boundaries without introducing new exposure. The one SUGGESTION is a prose-clarity note; the credential is removed in all interpretations, so it does not represent an exploitable gap.
"Any URL in the outbound set is checked for an `@`" was broader than the git-remote-only exception it introduced. Read literally, a connection string like `mongodb+srv://<user>:<secret>@<host>/<db>` would take the host-preserving strip instead of a shape marker — the credential goes either way, but the host and path would survive where the general rule redacts them, disclosing infrastructure for nothing. The rule now says git remote URLs, and states the boundary rather than leaving it to context: strip-and-keep applies where the remainder is load-bearing, because recovery re-resolves from a remote's surviving host and path; nothing re-resolves from a database host, so everywhere else the marker still wins. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 1m 26s —— View job PR Review —
|
| Finding | Status |
|---|---|
Handoff origin: embeds raw credential-bearing remote URLs |
Closed a9ee2dc |
Widening globs under unverified cwd |
Closed a9ee2dc |
| Checklist satisfied without reading credential-stripping rule | Closed ae3a497 |
| Rule conflict: no precedence stated between general (shape marker) and git-URL (strip-and-keep) rules | Closed 001808c |
| Scope: "any URL" could apply strip-and-keep to non-git credential-bearing URLs | Closed 24c74ea |
Verdict
All previously identified findings are resolved. This commit is a clean, targeted fix: the exception is now bounded by its rationale rather than implied by context, and the non-generalization paragraph makes the boundary explicit without duplicating prose from the rest of the rule. Ready to merge.
|
Claude finished @kyle-sexton's task in 1m 20s —— View job Security Review — PR #1780 (latest commit
|
| Finding | Resolution |
|---|---|
Handoff origin: embedded raw credential-bearing git remote URLs |
Fixed a9ee2dc |
Widening globbed under unverified cwd (home-directory sweep) |
Fixed a9ee2dc |
| Checklist satisfied without reading credential-stripping rule | Fixed ae3a497 |
| Two rules prescribed different outputs for same class, no precedence stated | Fixed 001808c |
| Strip-and-keep exception scoped to "any URL" — applies to non-git credential URLs | Fixed 24c74ea |
No new security issues found
The commit is confined to the prose rule for the git-URL exception and the CHANGELOG. No logic changes, no new code paths, no new surfaces. The consumer-side rule (find-handoff/SKILL.md) was not modified and remains correctly scoped.
Ready to merge from a security standpoint.
|
Classification of the six re-review comments triggered by
Verified: |
|
Per-finding dispositions for the restatements carried by the re-review rounds. Each row below is a finding a later review round re-listed while confirming it closed; recording the disposition explicitly rather than leaving it implied in the originating thread, since a restatement in an open comment is its own work item.
No open findings remain on this PR. Final head |
The defect
/session-flow:handoffwrote the save-point to an absolute location but emitted a rootlesspath in the copy-paste resume prompt. This was contract-specified, not a model slip:
reference/save-point.mddefined the directive asRead @<handoffs-dir>/<TS>-handoff-<topic>.mdwhere<handoffs-dir>is "the path the write stepactually used" — and
<memory_dir>is repo-relative by contract, so the one artifact an operatorcarries across
/clearlost the root the file hangs off.Pasted into a session whose cwd is not the worked-in repository root, the
@-reference resolvessomewhere else. When that somewhere else has its own
.work/handoffs/— true of any home directorythat has run
/handoffbefore — the failure presents as "the file is missing" rather than "thepath has no root", which #1644 correctly calls the most expensive shape to diagnose. It is not only
a cross-repo problem: a resuming session sitting in a subdirectory of the right repo fails the
same way.
/session-flow:find-handoff, the skill that exists to recover exactly this, carried the samesingle-root assumption — its transcript rung found the correct directive, resolved it against the
source transcript's
cwd, and then discarded the candidate on the existence check.The change
Producer (
reference/save-point.md).specified rather than left to the model: the directive survives into transcript JSONL, where a
backslash is escaped again, and
find-handoffgreps that record.Handoff origin:line inside the rails names the repository identity and the repo-relativepath, so a resume on a different machine or checkout can re-resolve. It is computed at emit
time from the repository actually written into — deliberately not a stored frontmatter field,
which is what kept this change out of schema territory. It sits inside the rails because the copy
region is what travels; below the rail it would be lost on paste.
@mention is documented as an accelerator, not the mechanism. Official docs state an@reference's path "can be relative or absolute"(common-workflows),
but document no drive-letter or whitespace-bearing form — so expansion is treated as unverified
there, and the directive is written to stay actionable without it (the same line states the full
absolute path, which a resuming session reads directly). That is what makes rooting a strict
improvement rather than a trade.
Absolute is not new to this engine:
reference/topic-docs.mdalready lands no-project-root handoffsunder
${CLAUDE_PLUGIN_DATA}/topic-docs/handoffs/"with the absolute path announced prominently".Same condition, reached a different way.
Consumer (
skills/find-handoff/SKILL.md).repo-relative path and is still on disk, so a detector that recognizes only rooted directives
would stop recovering the entire existing corpus. Matching happens on the
…handoffs/<TS>-handoff-…shape both forms share; they diverge only at the existence check.miss because resolving against the producer's
cwdis an inference; a rooted miss because anabsolute path is machine-local and a resume on another machine or checkout cannot satisfy it. The
rooted miss is exactly what
Handoff origin:exists for, so the existence check reads that lineand re-resolves against the repository it names before giving up. Either way: one bounded,
read-only widening over repository roots already in hand, then surfaced at the confirm gate with
the directive verbatim — and the gate names which failure it was, because "the path has no
root" and "nothing is at that absolute path on this machine" send an operator to different places,
while "missing" sends them nowhere. Discarding on miss is the specific behavior that made the
recovery ladder unable to recover the failure it was written for.
Handoff origin:is a resolution input, not a detection signal. It cannot admit or reject acandidate, so it is not a fourth key — it is read only after a candidate qualifies, at the
existence check. The signal summary says so rather than listing three signals while the ladder
depends on a fourth thing.
An independent fresh-context review of this diff caught the rooted-miss hole: the first revision
consulted
Handoff origin:only on the rootless branch — where the contract says it can neverappear, since the line shipped with the rooted form — leaving the one case it exists for as the one
case nothing handled, which fell through to discard-on-miss and reintroduced the defect one path
over. That, and the signal-label collision with the
/loopre-arm note's existing "fourth signal",are fixed in the second commit.
What this PR deliberately does NOT do
It does not fully satisfy #1644's line 176 ("rung 1's missing repo-correlation check should be
closed in the same change"). Closing it needs durable repository identity stored in the handoff
file — a new frontmatter field — which is a cross-cutting schema change every handoff already on
disk would lack, and which every consumer must then tolerate the absence of. That is a decision on
its own merits, now filed as #1778 with the options laid out.
A weaker substitute (read the repository off the producer transcript) was considered and rejected on
evidence: it depends on a transcript that may be absent — while
find-handoff's own Gotchas saytranscripts are the reliable index precisely because the filesystem is not — and it returns nothing
for every rootless legacy handoff, i.e. exactly where the check is needed. Shipping it would have
produced a check that looks closed and is not.
Instead, rung 1 now states the gap in place, so the next reader does not mistake it for closed.
Verification
All run locally in the PR worktree against
origin/main:scripts/check-changelog-parity.sh --check— every versioned plugin has a CHANGELOG.mdscripts/check-changelog-parity.sh --check-bump origin/main— 0.17.19 → 0.17.20 has its## [0.17.20]entry, newly addedscripts/check-changelog-parity.sh --check-order— all 71 changelogs newest-first, no duplicatesscripts/check-changed-skills.sh origin/main— 2 skills checked, 0 failed (find-handoff carriesthe pre-existing >200-line soft warning; cap is 500, it is at 394)
scripts/check-skill-portability.sh origin/main— no unexcused coupling tokensscripts/validate-plugins.sh— all plugin manifests + catalog validscripts/check-orphaned-fixtures.sh --check,check-contract-slice-prune.sh --check-diff origin/main,check-cross-plugin-source-drift.sh --check— all passmarkdownlint-cli2 "plugins/session-flow/**/*.md"— 36 files, 0 errorsparse-transcript.test.sh,observer.test.sh) — PASSevals.jsonfiles validate againstplugins/skill-quality/reference/evals.schema.json.Eval coverage added for the producer emitting a rooted path when cwd is not the worked-in repo
(handoff ci: onboard to the CI platform (ci-workflows + standards) #4), both-forms acceptance (find-handoff chore: adopt widened comment-hygiene policy and re-pin ci-workflows @9567b8b #9), the rootless UNRESOLVED path (build(deps): bump ci-workflows pin to b6431a1 (PSSA RULE_ERROR retry fix) #10, with its
prompt pinned to the pre-rooted directive so the branch is unambiguous), and the rooted miss
re-resolved via
Handoff origin:on another machine (fix(markdown-formatter): harden hook + simplify plumbing #11). find-handoff eval chore: initialize marketplace scaffold #1's cwd-resolutionexpectation was made form-aware so it no longer asserts the old single-form behavior.
The harness claim this change rests on was verified against current official docs this session
rather than recalled, per the repo's fresh-docs mandate; the drive-letter and whitespace edge is
explicitly flagged as not covered by those docs and is handled by not relying on expansion.
Related
not cwd's project root); adjacent cause, separately tracked, not required by this fix
the repository in play
🤖 Generated with Claude Code
https://claude.ai/code/session_01RhS3T7ShwJgKTrvk2Mvd3C