Skip to content

fix(ops): operator export scripts honor --help and refuse out-of-repo output paths - #98

Closed
nish3451 wants to merge 20 commits into
mainfrom
fix/operator-export-cli-help-lane1-20260812
Closed

fix(ops): operator export scripts honor --help and refuse out-of-repo output paths#98
nish3451 wants to merge 20 commits into
mainfrom
fix/operator-export-cli-help-lane1-20260812

Conversation

@nish3451

Copy link
Copy Markdown
Collaborator

Closes the lane item: [unreviewed-by-grok] Operator export scripts ignore --help and write/overwrite cockpits and mission artifacts anywhere.

What

Operator export scripts ignored --help / -h and silently regenerated tracked ops artifacts (cockpits like growth-cockpit, sales-cockpit, recording-cockpit; missions like daily-money-mission; plus live-metrics, proof-library, sender-setup-guide, 11-10-proof-run, competitive-proof-matrix, market-parity-benchmark-2026) on every help invocation. They also accepted --output / --html / --ops / --loom-links paths that escape the repository and could write or overwrite files anywhere on the machine.

Changes

  • New scripts/lib/operator-cli.mjs
    • handleHelp(args, usage) — prints usage and exits 0 before any work when --help / -h is present.
    • resolveOutputPath(value, {flag, fallback}) — resolves operator-supplied output paths against the service repository root and refuses paths that escape it via absolute paths, .. traversal, or symlink escapes (clear error, exit 1, no file created).
  • All 21 active npm-script-backed export scripts now call handleHelp first and route every write (and the proof-run loom-links path) through resolveOutputPath.
  • export-internal-dashboard.mjs no longer writes its parity scratch file to /tmp; it uses a gitignored runs/ scratch path cleaned up after use.
  • test-active-operator-surfaces.mjs extended:
    • every active export script must exit 0 on --help, print usage, and leave live-metrics.md, the proof library, and the daily money mission untouched;
    • escape probes: --output=../…, absolute /tmp/…, ../../ html path, --loom-links=../…, --ops=/tmp/…, and an in-repo symlink escape are all refused without creating the file.

Retired export scripts (no npm wiring, e.g. export-owned-*, export-full-stack-growth-map) are not part of the active operator surface and are intentionally untouched.

Validation

  • npm run ci: every suite passes (service-engine, sales-intake, active-offer-projection, active-operator-surfaces, direction-proof-gate, client-readiness-contract, validated-service-client, client-acceptance-gates, product-truth, human-service-kit, design-system-proving-lab, retention, agency-defaults, claims, send-readiness, all public-page suites, and node --check on every script). 630 checks, 0 failures.
  • Direct repro: node scripts/export-growth-metrics.mjs --help and node scripts/export-proof-library.mjs --help print usage, exit 0, and leave tracked artifacts untouched; --output=/tmp/… and --output=../… are refused with exit 1 and create nothing.

Relationship to existing PRs

Prior attempts at this same lane item: #36, #44, #55 (all stale bases) and #95 (recording exporters only, fresh but narrower). This is a fresh implementation on current main covering the full active export surface.

…-repo output paths

Export scripts ignored --help / -h and silently regenerated tracked cockpits,
missions, and other operator artifacts on every help invocation. They also
accepted --output / --html / --ops / --loom-links paths that could write or
overwrite files anywhere on the machine.

- New scripts/lib/operator-cli.mjs: handleHelp() prints usage and exits 0
  before any work; resolveOutputPath() resolves operator-supplied output
  paths against the service repository root and refuses escapes via
  absolute paths, '..' traversal, or symlinks.
- All 21 active npm-backed export scripts call handleHelp first and route
  every write through resolveOutputPath. The internal dashboard's parity
  scratch file moves from /tmp to a gitignored runs/ path cleaned up
  afterwards.
- test-active-operator-surfaces.mjs: every active export script must exit 0
  on --help, print usage, and leave live metrics, the proof library, and the
  daily money mission untouched; traversal / absolute / html / loom-links /
  ops / symlink escape probes are refused without creating files.

@greptile-apps greptile-apps 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.

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@nish3451, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 34 minutes

Limit details: You’ve used the included review currently available.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Free

Run ID: ffe8a20d-5753-47b2-ae37-efdc7d922887

📥 Commits

Reviewing files that changed from the base of the PR and between a7d9961 and 1c95919.

📒 Files selected for processing (11)
  • scripts/export-client-delivery-cockpit.mjs
  • scripts/export-daily-money-mission.mjs
  • scripts/export-followup-cockpit.mjs
  • scripts/export-growth-cockpit.mjs
  • scripts/export-growth-doctor.mjs
  • scripts/export-lead-scoring-cockpit.mjs
  • scripts/export-managed-it-one-pager.mjs
  • scripts/export-market-learning-review.mjs
  • scripts/export-market-proof-cockpit.mjs
  • scripts/export-prospect-outbox.mjs
  • scripts/export-sales-cockpit.mjs

Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands.

@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: 517ee8a6e6

ℹ️ 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".

Comment on lines +44 to +48
while (!existsSync(existing)) {
const parent = dirname(existing);
if (parent === existing) break;
existing = parent;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject dangling output symlinks

When the requested output itself is a dangling symlink to a nonexistent external file, existsSync(existing) returns false, so this loop climbs past the symlink and validates only its in-repository parent. The subsequent writeFileSync follows the dangling link and creates the external target, leaving every exporter using this helper vulnerable to the out-of-repository write the change is intended to prevent; inspect path components with lstat/readlink or otherwise reject symlinks before writing.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

Comment thread scripts/export-recording-queue.mjs Outdated
const outputDir = outputPath.split("/").slice(0, -1).join("/");
if (outputDir) mkdirSync(outputDir, { recursive: true });
writeFileSync(outputPath, `${lines.join("\n")}\n`);
writeFileSync(resolveOutputPath(outputPath), `${lines.join("\n")}\n`);

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 Validate the queue path before creating its directory

For an escaping value such as --output=/tmp/new-parent/queue.md, the preceding mkdirSync(outputDir) creates /tmp/new-parent before this call detects the escape and exits. The command therefore still modifies the filesystem outside the repository despite reporting that the path was refused; resolve and validate the path first, then derive and create its directory from the validated result.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

`;

const outputDir = outputPath.split("/").slice(0, -1).join("/");
const resolvedOutputPath = resolveOutputPath(outputPath);

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 Validate the cockpit path before regenerating dependencies

When --output escapes the repository, this validation is reached only after the calls near the top of the script have run the recording, scoring, outbox, mission, metrics, proof, doctor, and sender exporters. Consequently, an invocation such as growth:cockpit -- --output=/tmp/x exits with a refusal but has already overwritten numerous default repository artifacts—the same accidental regeneration this safety work is meant to avoid. Resolve the requested output immediately after parsing arguments, before invoking any child exporter.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@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: b1163a38c1

ℹ️ 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".

["scripts/export-market-benchmark.mjs", ["--ops=/tmp/escape-ops.md"], "/tmp/escape-ops.md"]
]
for (const [script, args, escapePath] of escapeProbes) {
rmSync(escapePath, {force: true})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Isolate escape fixtures before deleting them

When /tmp/escape-cockpit.html, /tmp/escape-ops.md, /tmp/escape-metrics.md, or even /escape-mission.html already belongs to another process or user, this loop unconditionally deletes that file before running the probe; the later escape-symlink-outside cleanup similarly removes a fixed sibling directory recursively. Because npm test runs this script and CI commonly runs with broad filesystem permissions, a test invocation can destroy unrelated data. Create a separate external directory with mkdtempSync and clean up only that uniquely owned directory.

Useful? React with 👍 / 👎.

Comment thread scripts/export-internal-dashboard.mjs Outdated
Comment on lines +59 to +61
const parityScratchPath = "runs/.internal-dashboard-parity.md";
const parity = runJson(["scripts/check-market-parity-readiness.mjs", "--skip-kit", `--output=${parityScratchPath}`]);
try { rmSync(join(serviceRoot, parityScratchPath), { force: true }); } catch {}

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 Preserve pre-existing dashboard scratch files

When runs/.internal-dashboard-parity.md already exists, every dashboard export passes that fixed path to the parity exporter, which overwrites it, and then deletes it unconditionally. This silently destroys repository data that predates the command; use a uniquely created temporary path and clean it in a finally block, or refuse to replace an existing file.

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@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: 8dae7ddbd3

ℹ️ 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".

Comment thread scripts/export-market-benchmark.mjs Outdated
Comment on lines +349 to +350
write(outputPath, markdown);
write(opsPath, markdown);
write(htmlPath, html);
write(opsPath, markdown, "--ops");

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 Validate every benchmark path before writing

When a secondary destination escapes the repository, such as --ops=/tmp/escape-ops.md or an escaping --html, the first write(outputPath, markdown) has already overwritten the default benchmark before the later write rejects that destination; the earlier metrics exporter also regenerates live-metrics.md. Resolve and validate all three requested paths before running exporters or writing any artifact so a refused invocation remains side-effect free.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@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: 212197fdbe

ℹ️ 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".


function write(path, content) {
const dir = path.split("/").slice(0, -1).join("/");
const resolved = resolveOutputPath(path);

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 Validate mission outputs before running exporters

When growth:mission receives an escaping --output or --html, validation does not reach this call until the final writes. Before then, the section at lines 201-222 runs ten child exporters and may refresh prospects/loom-links.txt; with an escaping --html, it also writes the requested Markdown output first. The command therefore reports a refusal only after overwriting repository artifacts, contrary to the plan's zero-write verification requirement. Resolve both destinations immediately after parsing them, before invoking exporters or updating the Loom template.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@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: 6ca592d6ca

ℹ️ 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".

Comment thread scripts/export-internal-dashboard.mjs Outdated
Comment on lines +489 to +490
write(resolveOutputPath(outputPath), markdown);
write(resolveOutputPath(htmlPath, { flag: "--html" }), html);

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 Validate dashboard destinations before regenerating dependencies

When either destination escapes the repository, validation is deferred until these final writes, after the calls at lines 51–73 have already regenerated growth metrics, the doctor report, proof surfaces, rehearsal artifacts, and the sender guide; an escaping --html also overwrites the Markdown dashboard before being rejected on line 490. Resolve both destinations immediately after parsing so a refused dashboard invocation remains side-effect free.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

Comment on lines 420 to +421
write(outputPath, markdown);
write(htmlPath, html);
write(htmlPath, html, "--html");

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 Validate proof-cockpit HTML before writing artifacts

When --html escapes the repository, the command reaches this validation only after check-market-proof-run.mjs has overwritten runs/market-proof-run-check.md and line 420 has overwritten the requested Markdown cockpit. The command then reports refusal despite already modifying repository artifacts, so resolve both destinations before invoking the checker or performing either write.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

Comment on lines 301 to +302
write(outputPath, markdown);
write(htmlPath, html);
write(htmlPath, html, "--html");

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 Validate learning-review HTML before regenerating metrics

With an escaping --html, this second write rejects the path only after the metrics exporter at line 62 has refreshed growth-brain/ops/live-metrics.md and line 301 has overwritten the Markdown learning review. Resolve both output paths before running exporters or writing either artifact so an invalid destination cannot cause partial regeneration.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

Comment on lines +394 to +395
write(outputPath, markdown);
write(htmlPath, html);
write(htmlPath, html, "--html");

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 Validate rehearsal HTML before writing Markdown

When only --html escapes the repository, line 394 has already overwritten the Markdown rehearsal report before this call rejects the HTML destination. Pre-resolve both requested paths before the first write so a refused invocation does not leave a partially updated artifact set.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

Comment thread scripts/export-sender-setup-guide.mjs Outdated
Comment on lines +255 to +256
write(outputPath, markdown);
write(htmlPath, html);
write(htmlPath, html, "--html");

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 Validate sender-guide HTML before writing Markdown

When --html points outside the repository, the Markdown sender guide is overwritten on line 255 before this call validates and rejects the HTML path. Resolve both destinations before either write so a refused command cannot partially refresh the guide.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@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: e299770d68

ℹ️ 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".

`;

const outputDir = outputPath.split("/").slice(0, -1).join("/");
const resolvedOutputPath = resolveOutputPath(outputPath);

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 Validate the doctor output before regenerating reports

When --output escapes the repository, validation occurs only here, after the metrics and rehearsal exporters have already overwritten their default artifacts at lines 151–154. Resolve the requested destination before invoking those exporters so a refused growth:doctor command remains side-effect free.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

Comment thread scripts/export-recording-cockpit.mjs Outdated
`;

const outputDir = outputPath.split("/").slice(0, -1).join("/");
const resolvedOutputPath = resolveOutputPath(outputPath);

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 Validate recording cockpit output before drafting messages

When an active prospect exists and --output escapes the repository, the mapping at lines 79–81 runs draft-prospect-message.mjs, which overwrites that prospect's next-message.md, before this validation rejects the destination. Resolve the output before processing prospects so an invalid cockpit invocation cannot mutate prospect records.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

`;

const outputDir = outputPath.split("/").slice(0, -1).join("/");
const resolvedOutputPath = resolveOutputPath(outputPath);

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 Validate follow-up output before refreshing messages

When a prospect has a due follow-up and --output escapes the repository, ensureMessage() at line 94 overwrites the prospect's next-message.md before this late validation exits. Validate the destination before enumerating due prospects so a refused follow-up export does not alter repository data.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

`;

const outputDir = outputPath.split("/").slice(0, -1).join("/");
const resolvedOutputPath = resolveOutputPath(outputPath);

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 Validate outbox output before regenerating messages

When an approved send-package prospect exists and --output escapes the repository, the outbox calls ensureMessage() at line 121 and overwrites next-message.md before reaching this validation. Resolve the destination before building the prospect list so an invalid outbox request cannot modify prospect artifacts.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@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: b2164ef995

ℹ️ 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".

existing = parent;
}
const realRoot = realpathSync(root);
const realRel = relative(realRoot, realpathSync(existing));

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 Replace hard-linked destinations atomically

When the requested in-repository destination already exists as a hard link to a file outside the repository on the same filesystem, realpathSync(existing) still reports the safe-looking in-repository pathname, so this check passes and the exporters' subsequent writeFileSync calls truncate the shared external inode. Reject multiply linked destination files or write to a new temporary file and atomically rename it over the destination so the out-of-repository write guarantee also survives hard-link tampering.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@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: 36ab621630

ℹ️ 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".

Comment thread scripts/export-growth-metrics.mjs Outdated

const outputDir = outputPath.split("/").slice(0, -1).join("/");
const resolvedOutputPath = resolveOutputPath(outputPath);
const outputDir = resolvedOutputPath.split("/").slice(0, -1).join("/");

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 Derive resolved output directories with path.dirname

On Windows, resolveOutputPath() returns a platform-native absolute path such as C:\repo\new\metrics.md, so splitting it on "/" produces no parent directory. When a user selects an in-repository output whose parent does not yet exist, mkdirSync is skipped and writeFileSync fails with ENOENT; this pattern is repeated in several modified exporters. Use path.dirname(resolvedOutputPath) so the documented recursive directory creation works across platforms.

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@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: fab7985d30

ℹ️ 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".

Comment thread scripts/export-internal-dashboard.mjs Outdated
}
const parity = runJson(["scripts/check-market-parity-readiness.mjs", "--skip-kit", "--output=/tmp/tinystudio-internal-dashboard-parity.md"]);
const parityScratchPath = "runs/.internal-dashboard-parity.md";
const parity = runJson(["scripts/check-market-parity-readiness.mjs", "--skip-kit", `--output=${parityScratchPath}`]);

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 Validate the parity scratch path before invoking the checker

When the ignored runs/ path is a symlink to a directory outside the repository, this child command writes .internal-dashboard-parity.md through that symlink and the following cleanup deletes the external file. The invoked checker merely joins serviceRoot with --output and passes it to writeFileSync (scripts/check-market-parity-readiness.mjs:13,28-31), bypassing resolveOutputPath; validate this scratch destination or use a safely created temporary directory before running the checker.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@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: 33aad2b328

ℹ️ 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".

Comment thread scripts/export-market-proof-run.mjs Outdated
? "prospects/kit-proof-run-loom-links.txt"
: "prospects/loom-links.txt";

const resolvedLoomLinksPath = resolveOutputPath(loomLinksPath, { flag: "--loom-links" });

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 Validate the proof-run parity scratch path

When the ignored prospects/ directory is a symlink outside the repository and the caller supplies a safe --loom-links path under runs/, this validation succeeds, but the section at lines 207–214 still invokes check-market-parity-readiness.mjs with prospects/market-proof-run-parity.md. That checker directly joins the path to serviceRoot and writes it (scripts/check-market-parity-readiness.mjs:12-13,28-31,227), after which this exporter deletes it, so the command can write and remove an external file despite validating both operator-provided destinations; validate the parity scratch destination as well or create it in a safely owned temporary directory.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@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: 1955e418a5

ℹ️ 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".

`;

const outputDir = outputPath.split("/").slice(0, -1).join("/");
const resolvedOutputPath = resolveOutputPath(outputPath);

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 Anchor prospect reads to the service root

When SERVICE_REPO_ROOT differs from the current working directory, this now writes the cockpit under the service repository, but the prospect scan at line 45 still reads the relative prospects directory from the current working directory. Consequently, running the exporter from another workspace can copy that workspace's prospect names and details into the service repository's HTML; resolve the input root against serviceRoot as well before generating the output.

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@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: b41a2de5d5

ℹ️ 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".

`;

const outputDir = outputPath.split("/").slice(0, -1).join("/");
const resolvedOutputPath = resolveOutputPath(outputPath);

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 Anchor teleprompter inputs to the service root

When SERVICE_REPO_ROOT differs from the current working directory, this writes the teleprompter into the service repository, but the prospect scan at line 73 still reads the relative prospects directory from the current working directory. The generated service-repository cockpit can therefore expose another checkout's prospect details and omit the intended repository's records; resolve the input root against serviceRoot before generating the output.

AGENTS.md reference: AGENTS.md:L2-L3

Useful? React with 👍 / 👎.

…-cli-help

# Conflicts:
#	scripts/export-growth-metrics.mjs
#	scripts/export-internal-dashboard.mjs
#	scripts/export-market-benchmark.mjs
#	scripts/export-market-proof-run.mjs
#	scripts/export-proof-library.mjs
#	scripts/export-recording-cockpit.mjs
#	scripts/export-recording-queue.mjs
#	scripts/export-recording-rehearsal-check.mjs
#	scripts/export-recording-teleprompter.mjs
#	scripts/export-sender-setup-guide.mjs
#	scripts/test-active-operator-surfaces.mjs
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@nish3451

Copy link
Copy Markdown
Collaborator Author

Superseded by #56. This PR covers 11 exporters (78% of its change is already inside #44's older 20-script version); #56 covers all 29 via the shared helper. Closing in favour of #56.

@nish3451

Copy link
Copy Markdown
Collaborator Author

Correction to my closing comment above: the keeper for this cluster is #160, not #56.

I had wrongly concluded that main had no exporters wired for --help. In fact main already wires 18 of 29 exporters to scripts/lib/operator-cli.mjs; only 11 remain, and #160 covers exactly those 11 using main's current helper. #56 has since been closed because it would revert main's newer operator-cli.mjs and re-apply an older calling convention across 18 already-finished exporters.

This PR stays closed either way — its content is superseded by what is already on main plus #160 — but the pointer should be to #160.

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