fix(ops): every growth/ops exporter honors --help without touching tracked or retired artifacts - #56
fix(ops): every growth/ops exporter honors --help without touching tracked or retired artifacts#56nish3451 wants to merge 5 commits into
Conversation
…-repo output paths Every active operator export script now handles --help/-h before doing any work: it prints usage and exits 0 without writing or overwriting any cockpit or mission artifact. Operator-supplied output paths (--output, --html, --ops, --loom-links) are resolved against the service repository root and refused when they escape it via absolute paths, .. traversal, or symlinks -- including dangling symlinks whose target writeFileSync would silently create outside the repo -- so an export can no longer write or overwrite files anywhere. - Add scripts/lib/operator-cli.mjs with handleHelp() and resolveOutputPath() - Wire both into all 21 npm-script-backed export scripts; validate every output path before any dependency exporter runs or any artifact is written - Route the internal-dashboard parity scratch inside the repo (unique runs/ path, cleaned up in finally) instead of /tmp - Extend test-active-operator-surfaces.mjs: --help and -h contract for every active export script (exit 0 + usage + untouched artifacts), escape probes confined to a test-owned tmp directory, and symlink/dangling-symlink refusal probes
…wth/ops artifacts stay untouched The first pass covered the 21 npm-backed active exporters. Eight scripts in scripts/ still ignored --help and ran their full export when asked for help: - export-full-stack-growth-map, export-owned-handoff-loom-cockpit, export-owned-product-case-studies, export-owned-product-workflow-proofs recreate retired growth-brain/ops artifacts (owned-*, full-stack-growth-map.*) that the active operator surface contract requires to never exist - export-owned-startup-proof-capture seeds owned client folders and rewrites client proof packets - export-client-channel-readiness, export-client-repeatable-workflow, export-client-weekly-report rewrite client runtime scorecards and reports All eight now call handleHelp() before any work: --help/-h prints usage and exits 0 without writing. The three owned-* writers and the two client writers with --output/--html flags also route their output paths through resolveOutputPath() so an operator-supplied path can no longer escape the repository. test-active-operator-surfaces.mjs now asserts the --help/-h contract for all 29 export scripts, that no retired broad-service artifact is recreated by --help/-h, that export-owned-startup-proof-capture does not seed owned client folders on --help, and that the owned-*/client writers refuse escaping output paths.
…t-count checks stay isolated
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
Warning Review limit reached
Next review available in: 32 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (31)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2071d9e97f
ℹ️ 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".
| } | ||
| } | ||
| } | ||
| return resolved; |
There was a problem hiding this comment.
Keep exported artifact paths repository-relative
Returning resolved changes every caller that reuses the write path in its JSON or generated content from a repository-relative path to an absolute host path. For example, a normal metrics export now reports /workspace/.../growth-brain/ops/live-metrics.md, and export-internal-dashboard.mjs embeds those absolute values in its dashboard, making artifacts machine-specific and exposing temporary checkout paths in tests. Preserve the raw repository-relative value for output and reporting while using the resolved value only for filesystem operations, as export-market-benchmark.mjs already does.
Useful? React with 👍 / 👎.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 49436b273a
ℹ️ 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".
| // that a dangling symlink -- one whose target writeFileSync would silently | ||
| // create outside the repository -- is caught as well as a live one. | ||
| export function resolveOutputPath(value, { flag = "--output", fallback } = {}) { | ||
| const raw = value === undefined || value === null || value === "" ? fallback : value; |
There was a problem hiding this comment.
Reject explicit empty output values
When an output option is supplied with an empty value—for example, npm run growth:metrics -- --output="$UNSET" when the variable is unset—this treats it as though the option were omitted and silently writes the fallback path. For exporters whose fallback is tracked, that unexpectedly overwrites artifacts such as growth-brain/ops/live-metrics.md; before this change, writing to the empty filename failed instead. Reserve the fallback for undefined/null and refuse an explicitly empty value.
Useful? React with 👍 / 👎.
The fleet keeps dispatching the same finding to multiple lanes, producing duplicate same-fix PR pairs: #36/#44 and #55/#56 are byte-identical or near-identical patches of the operator export --help fix, #39/#49 the offername article fix, #40/#52 the recording exporter --help fix, plus #38/#48/#51, #30/#61/#72, #45/#64, #42/#60, #43/#54 and #46/#74. Add a PR Duplicate Guard: - scripts/check-pr-duplicates.mjs compares a PR's diff against every other open PR (shared changed-file coverage >= 0.8 and patch similarity >= 0.5). Calibrated on all 79 open PRs on 2026-08-11: every pair above the thresholds was a genuine duplicate-cluster member, zero false positives. - .github/workflows/pr-duplicate-guard.yml runs it on every PR event and posts one marker comment naming the duplicate(s) and the canonical PR; the check fails loudly when a duplicate is found. Informational, not required. - scripts/test-pr-duplicates.mjs covers parsing, similarity, detection, and comment upsert with an injected API; wired into npm ci and npm test.
|
Closing in favour of #160 — superseded by This PR rewrites all 29 operator/growth exporters plus The only genuinely outstanding work is the 11 exporters still unwired on Note: I earlier closed #36, #44, #55, #98, #40, #52 and #95 citing this PR as the keeper. That attribution was wrong and I have corrected it on each of them — the keeper for this cluster is #160. |
Closes the [unreviewed-by-grok] item: Growth/ops exporters ignore
--helpand overwrite tracked ops artifacts (live-metrics, proof-library).Problem
node scripts/export-growth-metrics.mjs --helpignored--help, ran the full export, and overwrote the trackedgrowth-brain/ops/live-metrics.md(same forproof-library.mdand every other exporter). Eight more scripts inscripts/still ignored--helpand ran their entire export when asked for help — includingexport-full-stack-growth-map/export-owned-*, which recreate retiredgrowth-brain/ops/artifacts the active operator-surface contract requires to never exist.Fix (3 commits)
handleHelp()before any work —--help/-hprints usage and exits 0 without writing. All operator-supplied output paths (--output,--html,--ops,--loom-links) are resolved against the repo root viaresolveOutputPath()and refused when they escape via absolute paths,..traversal, or (dangling) symlinks. Shared helpers inscripts/lib/operator-cli.mjs.full-stack-growth-map,owned-handoff-loom-cockpit,owned-product-case-studies,owned-product-workflow-proofs; owned-startup proof capture; client channel-readiness / repeatable-workflow / weekly-report): same--helpcontract; the 5 with--output/--htmlflags also refuse escaping output paths.test-active-operator-surfaces.mjsnow asserts the--help/-hcontract for all 29 export scripts, that no retired broad-service artifact is recreated by--help/-h, thatexport-owned-startup-proof-capturedoes not seed owned client folders on--help, and that the owned/client writers refuse escaping output paths.Verification
npm run ci— full gate passes (all suites, 0 failures;node --checkon every script)--helpprints usage, exits 0, and leaves the working tree byte-identical.Supersedes the earlier partial PRs for this item (#36, #44, #55); this branch is the complete pass over all 29 export scripts based on fresh
origin/main.