Deferred from PR #466's triage (round 2, unreviewed head)
PR #466 (fix/issue-465, head 1f7fdac) fixed two review-round-1 findings by
requiring a rollout-sourced Codex cwd to be non-blank and absolute
before it reaches the .hypignore policy gate (sessionMetaCwd in
src/core/codex/rollout_session_meta.js, shared with the codex backfill).
The PR's own new doc, LLP 0143 #usable-cwd,
records one remaining gap on purpose rather than silently. This issue tracks
that gap so it doesn't only live in a decision doc's "Still outstanding" bullet.
The finding
hypaware-core/plugins-workspace/codex/src/exchange-projector.js:120-123
const cwd = firstString(codexContext?.cwd, readRecordedCwd(reqBody))
?? (codexContext?.session_id ? rolloutCwd?.resolve(codexContext.session_id) : undefined)
if (cwd) {
const policy = resolver.resolve(cwd)
if (policy.class === 'ignore') { ... return USAGE_POLICY_DROP }
}
codexContext?.cwd and readRecordedCwd(reqBody) (defined at
exchange-projector.js:880, reading reqBody.cwd / metadata.cwd /
metadata.user_id.cwd) are the Codex in-band cwd — the API-key route's
fast path (LLP 0083). Neither is passed through sessionMetaCwd or any other
absoluteness check. A relative value here reaches resolver.resolve(cwd)
directly, whose first act is path.resolve(cwd) against the daemon's
process cwd — the exact hazard PR #466 just closed for the rollout-fallback
source, reached through a different (in-band) source. This is the policy
gate itself, not only the row's stamped content (the same cwd value is
also passed to resolveRecordedContext at line 164 for enrichment, but line
120-123 is the drop decision).
Why PR #466 didn't fix this too
Per LLP 0143's consequences section, it is a different source with a
different trust story (client-supplied per-request, not a locally-written
rollout file), tightening it also touches row content (line 164), not only
the drop decision, so it is not a mechanical consequence of sharing
sessionMetaCwd. The branch was also already conflicting with #458 and #462
in this same file's neighborhood; a third change here was judged to add
avoidable conflict surface for a fix already at its 2-round review budget.
Why this issue is not blocked on #466
This code is already on master, unmodified by PR #466 (git diff c551d6e..1f7fdac -- hypaware-core/plugins-workspace/codex/src/exchange-projector.js
is empty). Whether or not #466 merges has no effect on this exposure either
way — it is actionable independent of #466's fate.
Suggested shape
Extend the same sessionMetaCwd-shaped predicate (or a general one) to
codexContext?.cwd / readRecordedCwd(reqBody) before they reach
resolver.resolve, deciding explicitly what happens to the stamped row
content when an in-band cwd is refused (null cwd vs. some other enrichment
fallback), since unlike the rollout source this value currently does double
duty as both gate input and recorded content.
Related
Deferred from PR #466's triage (round 2, unreviewed head)
PR #466 (
fix/issue-465, head1f7fdac) fixed two review-round-1 findings byrequiring a rollout-sourced Codex
cwdto be non-blank and absolutebefore it reaches the
.hypignorepolicy gate (sessionMetaCwdinsrc/core/codex/rollout_session_meta.js, shared with the codex backfill).The PR's own new doc, LLP 0143
#usable-cwd,records one remaining gap on purpose rather than silently. This issue tracks
that gap so it doesn't only live in a decision doc's "Still outstanding" bullet.
The finding
hypaware-core/plugins-workspace/codex/src/exchange-projector.js:120-123codexContext?.cwdandreadRecordedCwd(reqBody)(defined atexchange-projector.js:880, readingreqBody.cwd/metadata.cwd/metadata.user_id.cwd) are the Codex in-band cwd — the API-key route'sfast path (LLP 0083). Neither is passed through
sessionMetaCwdor any otherabsoluteness check. A relative value here reaches
resolver.resolve(cwd)directly, whose first act is
path.resolve(cwd)against the daemon'sprocess cwd — the exact hazard PR #466 just closed for the rollout-fallback
source, reached through a different (in-band) source. This is the policy
gate itself, not only the row's stamped content (the same
cwdvalue isalso passed to
resolveRecordedContextat line 164 for enrichment, but line120-123 is the drop decision).
Why PR #466 didn't fix this too
Per LLP 0143's consequences section, it is a different source with a
different trust story (client-supplied per-request, not a locally-written
rollout file), tightening it also touches row content (line 164), not only
the drop decision, so it is not a mechanical consequence of sharing
sessionMetaCwd. The branch was also already conflicting with #458 and #462in this same file's neighborhood; a third change here was judged to add
avoidable conflict surface for a fix already at its 2-round review budget.
Why this issue is not blocked on #466
This code is already on
master, unmodified by PR #466 (git diff c551d6e..1f7fdac -- hypaware-core/plugins-workspace/codex/src/exchange-projector.jsis empty). Whether or not #466 merges has no effect on this exposure either
way — it is actionable independent of #466's fate.
Suggested shape
Extend the same
sessionMetaCwd-shaped predicate (or a general one) tocodexContext?.cwd/readRecordedCwd(reqBody)before they reachresolver.resolve, deciding explicitly what happens to the stamped rowcontent when an in-band cwd is refused (null cwd vs. some other enrichment
fallback), since unlike the rollout source this value currently does double
duty as both gate input and recorded content.
Related
#usable-cwdand "Still outstanding" in Consequences).hypignoregate this feeds)