Skip to content

UN-4622 [FIX] Stop publishing the x2text service's port on the host - #2455

Open
ritwik-g wants to merge 5 commits into
mainfrom
UN-4622-x2text-drop-host-port
Open

ritwik-g wants to merge 5 commits into
mainfrom
UN-4622-x2text-drop-host-port

Conversation

@ritwik-g

@ritwik-g ritwik-g commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

What

  • docker/docker-compose.yaml: x2text-service no longer publishes port 3004 on the host. A commented-out 127.0.0.1:3004:3004 mapping is kept for local development.
  • tests/compose/docker-compose.test.yaml: the e2e overlay publishes it on loopback (127.0.0.1:3004), because the rig's readiness probe and e2e smoke test call x2text's health endpoint from the host (UNSTRACT_X2TEXT_URL, default http://localhost:3004).
  • docs/local-dev-setup-executor-migration.md, workers/sample.env, tests/README.md and tests/rig/runtime.py: note the opt-in for running workers, the backend or the rig's local runtime against the compose stack from the host.

Why

How

  • The ports entry is commented out, and the e2e overlay adds a loopback-only mapping.

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

  • Not for the docker-compose deployment. The backend and workers call x2text as http://unstract-x2text-service:3004 on the compose network (X2TEXT_HOST in backend/sample.env and workers/sample.env), which doesn't use the host port.
  • Anyone running the backend or workers on the host against the compose stack needs to uncomment the loopback mapping. The local-dev doc says so.
  • The rig's e2e stack keeps reaching x2text through the overlay's loopback mapping.
  • The rig's local runtime (e2e against a stack started with run-platform.sh) probes x2text at localhost:3004, so it needs the loopback mapping uncommented and run-platform.sh re-run with the same options. tests/README.md and tests/rig/runtime.py now say so.
  • The Helm chart is unaffected.

Database Migrations

  • None

Env Config

  • None

Relevant Docs

  • docs/local-dev-setup-executor-migration.md (updated)

Related Issues or PRs

Dependencies Versions

  • None

Notes on Testing

  • docker compose config renders x2text-service with no ports from docker/docker-compose.yaml alone, and with 127.0.0.1:3004 -> 3004 when the e2e overlay is added.
  • QA: on a docker-compose deployment, run text extraction (an Unstructured or LLMWhisperer adapter test connection plus a workflow run) and confirm it works. Then confirm curl http://<host>:3004/api/v1/x2text/health from another machine is refused.

Checklist

I have read and understood the Contribution Guidelines.

🤖 Generated with Claude Code

x2text-service is an internal service: the backend and workers reach it by
service name on the compose network. Keep a commented-out loopback mapping
for local development, and publish it on loopback in the e2e overlay, whose
readiness probe calls it from the host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Standardized review — round 1, review-deep (attack-surface deferral), tip 52a27a7

Mode: INITIAL. Diff: git diff 86a63b848923baaff183280609bb5ca878471e63 HEAD (merge base with freshly fetched origin/main; 4 files, 19 lines; file count matches GitHub). Plugin: unstract v2.1.80.

Verdict — APPROVE WITH NITS

Summary — Critical: 0 · High: 0 · Medium: 1 · Low: 0 · Lenses run: 19/19 (examined: 10; N/A: 9)

Signals: lenses 11 (compose and test-overlay config), 13 (test overlay changed), 16 (docs and comments), 17 (a stated default, "x2text is on localhost:3004", changed) raised.

Security deep-dive: not run. No Step 2a trigger is present: no new or modified endpoint, parser, authn path, untrusted-input construction, secret or input boundary. The change only removes a host-published port.

Findings

  1. [Medium] [Lens 3 / 13 / 17] — The rig's local e2e runtime now fails the smoke gate on x2text-service. Posted inline at docker/docker-compose.yaml:L137-L141.

Unanchored findings

  • Lens 1, PR body: the "Can this PR break any existing features" section covers backend and workers on the host, but not the rig's local runtime (finding 1).
  • Lens 13: CI e2e has not run on this PR, because ci-test.yaml skips e2e on drafts. The overlay merge is confirmed statically (see the lens 11 line). The end-to-end proof arrives only when the PR is marked ready. Confirm e2e is green before merging.

Lens checklist

  1. Spec & intent — Clean. The diff does what the body says, apart from the caveat in finding 1. The repo states no PR-title convention.
  2. Architectural fit & precedent — Clean. It mirrors the #2442 runner pattern exactly.
  3. Correctness & edge cases — See findings #1.
  4. Security — Clean (orchestrator). The change removes a host-published port and adds only a loopback mapping in the test overlay. No endpoint, auth, parser or secret is touched. Boundary sweep: N/A, because no log line, error path, outbound client or endpoint changed.
  5. Data integrity & migrations — N/A — no data or schema changes (orchestrator).
  6. Concurrency — N/A — no concurrency code (orchestrator).
  7. API & contract compatibility — Clean (orchestrator). No wire format changed. I searched the repo for host-port consumers: every in-network caller uses http://unstract-x2text-service:3004 (backend/sample.env, workers/sample.env, tools/classifier/sample.env). No .github/ workflow references 3004 or UNSTRACT_X2TEXT_URL. The only host consumer is the rig, covered in finding 1.
  8. Reliability & resilience — N/A — no runtime code changes (orchestrator).
  9. Performance & cost — N/A — config and docs only.
  10. Observability — N/A — no logs, metrics or code paths changed.
  11. Operational safety — Clean (orchestrator).
    • The overlay merges correctly: docker compose -f docker/docker-compose.yaml -f tests/compose/docker-compose.test.yaml config renders 127.0.0.1:3004 -> 3004, keeps the base image, env_file and depends_on, and creates no orphan service.
    • Upgrade path: run-platform.sh runs docker compose up -d, which recreates the container because its config changed. An existing deployment therefore drops the host mapping on its next run-platform.sh or up -d.
    • Until then, a container that is not recreated keeps the old 0.0.0.0:3004 mapping. That is expected Compose behaviour, but QA should recreate the stack before running the "refused from another machine" check.
  12. LLM/agent-specific — N/A — no model, prompt or tool changes.
  13. Testing — See findings #1. The overlay change itself is clean: every host-side x2text probe runs through ComposeRuntime, which layers the overlay.
  14. Dependencies & build — N/A — no dependency or build changes (orchestrator).
  15. Code quality — Clean.
    • Pinned gate, run by the orchestrator in check-only mode:
      • yamllint (key-duplicates) on both YAML files exits 0. The local version is 1.37.1; the pin is v1.38.0.
      • No added line has trailing whitespace.
      • No Python changed, so ruff is N/A.
    • markdownlint was not run: the tool is not installed locally.
  16. Doc & comment accuracy — Clean. Every claim in the four changed comments and docs was checked against the code, as follows.
    • the hostnames;
    • UNSTRACT_X2TEXT_URL usage in the readiness probe and smoke test;
    • docker compose up -d runner x2text-service is valid with the optional profile in the override;
    • the inline # in workers/sample.env is stripped by source and dotenv.
  17. Cross-document rule consistency — See findings #1 (tests/README.md:L204, tests/rig/runtime.py:L317). This was a manual repo-wide sweep for 3004, localhost:3004 and UNSTRACT_X2TEXT_URL. The merge-sweep script did not run, because the diff defines no identifiers to sweep for.
  18. On-prem deployment experience — N/A — no Helm chart, on-prem values or on-prem docs are touched (orchestrator).
  19. Scaling & workload lifecycle — N/A — no scaling or lifecycle values changed (orchestrator).

Agent-sourced lines: 1, 2, 3, 9, 10 and 15 (content) came from code-reviewer; 13 from pr-test-analyzer; 16 from comment-analyzer. All the others, and lens 15's pinned gate, were assessed by the orchestrator.

Open questions for the author

  • Is the local rig runtime used in practice? If it is, which remedy do you prefer: a doc note or a smoke-failure hint?

Assumptions made

  • docker compose up -d recreates x2text-service when its ports change. This is standard Compose config-hash behaviour, and I did not exercise it live.

cost: agents=3 wall=05:26 lenses-examined=10 of 19 files=4 lines=19

Comment thread docker/docker-compose.yaml Resolved
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Standardized review: round 2, review-deep (attack-surface deferral), tip 5e5f3f6

Mode: FOLLOWUP. Whole-PR diff: git diff 86a63b848923baaff183280609bb5ca878471e63 HEAD. That is the merge base with a freshly fetched origin/main: 6 files and 24 lines, and the file count matches GitHub. Round delta: git diff 52a27a71e 5e5f3f6cd, covering tests/README.md and a docstring in tests/rig/runtime.py. Plugin: unstract v2.1.80.

Verdict: APPROVE WITH NITS

Summary: Critical: 0 · High: 0 · Medium: 1 · Low: 1 · Lenses run: 19/19 (examined: 7; N/A: 12)

Prior context fetched: followup-fetch.sh exited 0 and fetched 6 of 6 files. The "since" boundary is 52a27a71e14abaf719fae1fc68a6718b7ad9a73e.

Scope change: NO. The delta only touches docs and a docstring at the prior finding's sites. It adds no new file, dependency, API, IaC or CI surface.

Signals: lenses 13 (a path under tests/), 16 (README and docstring) and 17 (restates the rule that x2text is not published on the host) raised.

Security deep-dive: not run. No Step 2a trigger is present, and the round delta is prose only.

Prior findings status

  • #1 [Medium] The rig's local e2e runtime fails the smoke gate on x2text-service: RESOLVED.
    • Evidence: tests/README.md:204 and tests/rig/runtime.py:318-320 now say x2text must be reachable at UNSTRACT_X2TEXT_URL, and that uncommenting the loopback ports entry gets you there. That remedy is correct: docker/docker-compose.yaml:139-141 carries the commented 127.0.0.1:3004:3004, and run-platform.sh:305 picks it up with no other change.
    • The second remedy, "add the overlay", was in my round-1 suggested fix. It turns out to be unsafe as worded; see new finding 1.
  • Unanchored item from round 1 (lens 1, PR body did not cover the local runtime): RESOLVED. The "Can this PR break" section now has a local runtime bullet.
  • Unanchored item from round 1 (lens 13, CI e2e not yet run): NOT RESOLVED. It is still pending, because e2e is skipping on the draft. Confirm e2e is green after the PR is marked ready.

New findings

  1. [Medium] [Lens 3 / 16]: "Add the e2e overlay" changes far more than x2text's port on a run-platform.sh stack. Posted inline at tests/README.md:204. The same clause is at tests/rig/runtime.py:320.
  2. [Low] [Lens 16 / 17]: The from_env docstring is left stale. tests/rig/runtime.py:140 is not in the diff, so it is listed under Unanchored findings below.

Unanchored findings

  • Finding 2 [Low] [Lens 16 / 17], tests/rig/runtime.py:140: "Defaults match the dev compose stack at docker/docker-compose.yaml."
    • This PR makes the sentence false for x2text. The default is http://localhost:3004 (runtime.py:151), and docker/docker-compose.yaml:137-141 no longer publishes that port.
    • It now contradicts the new docstring at runtime.py:318-320.
    • The runner default (localhost:5002) already did not match after #2442, so this PR widens an existing inaccuracy rather than creating it.
    • Suggested fix: delete the sentence (README:204 now states the correct rule), or qualify it: "except runner and x2text-service, which it does not publish on the host".
    • Verified at the merge base: the line is unchanged since 86a63b848.

Lens checklist

  1. Spec & intent: Clean. The delta delivers the remedy the round-1 finding asked for, and the PR body now matches. The title follows the TICKET [TYPE] text convention.
  2. Architectural fit & precedent: Clean. It mirrors how the runner's opt-in is documented in #2442.
  3. Correctness & edge cases: See findings #1.
  4. Security: Clean (orchestrator). The delta is prose only. The whole PR removes a host-published port and adds a loopback-only test mapping. Boundary sweep: N/A, because no log line, error path, outbound client or endpoint changed.
  5. Data integrity & migrations: N/A (orchestrator). No data or schema changes.
  6. Concurrency: N/A (orchestrator). No concurrency code.
  7. API & contract compatibility: N/A (orchestrator). No wire format changed in the delta. The round-1 consumer search still holds: git grep for localhost:3004 and UNSTRACT_X2TEXT_URL finds only the rig, the docs and the overlay.
  8. Reliability & resilience: N/A (orchestrator). No runtime code changes.
  9. Performance & cost: N/A. Docs only.
  10. Observability: N/A. No logs, metrics or code paths changed.
  11. Operational safety: N/A (orchestrator). The delta does not touch compose or any other config. The round-1 assessment of the compose change stands.
  12. LLM/agent-specific: N/A. No model, prompt or tool changes.
  13. Testing: N/A (orchestrator). No test logic changed. The only tests/ edits are a README row and a docstring. CI e2e is still pending (see Prior findings status).
  14. Dependencies & build: N/A (orchestrator). No dependency or build changes.
  15. Code quality: Clean.
    • Pinned gate: pre-commit.ci - pr passed at head 5e5f3f6. That run includes ruff v0.3.4 and markdownlint v0.42.0 as pinned in .pre-commit-config.yaml.
    • No added line has trailing whitespace.
    • I did not run local tools at the pinned versions; the local ruff is 0.1.0.
  16. Doc & comment accuracy: See findings #1, #2.
  17. Cross-document rule consistency: See findings #2. This was a manual repo-wide sweep for localhost:3004, UNSTRACT_X2TEXT_URL and "Defaults match the dev compose". The merge-sweep script did not run, because the diff defines no identifiers to sweep for.
  18. On-prem deployment experience: N/A (orchestrator). No Helm chart, on-prem values or on-prem docs are touched.
  19. Scaling & workload lifecycle: N/A (orchestrator). No scaling or lifecycle values changed.

Agent-sourced lines: 1, 2, 3, 9, 10 and 15 (content) came from code-reviewer; 16 came from comment-analyzer. All the others, and lens 15's pinned gate, were assessed by the orchestrator. pr-test-analyzer was not dispatched, because the round delta changes no test logic.

Open questions for the author

  • Is the overlay route worth keeping for local at all, given that the loopback uncomment is a complete fix on its own?

Assumptions made

  • pre-commit.ci's pass covers the delta files at the pinned hook versions. I did not run local tools at those versions.

cost: agents=2 wall=04:59 lenses-examined=7 of 19 files=6 lines=24

Comment thread tests/README.md Resolved
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Standardized review: round 3, review-deep (attack-surface deferral), tip 39e34d9

Mode: FOLLOWUP. Whole-PR diff: git diff 86a63b848923baaff183280609bb5ca878471e63 HEAD (merge base with a freshly fetched origin/main; 6 files, 28 lines; file count matches GitHub). Round delta: git diff 5e5f3f6cd 39e34d953, covering tests/README.md (the local runtime row) and two docstrings in tests/rig/runtime.py. Plugin: unstract v2.1.80.

Signals: lenses 13 (tests path changed), 16 (docstrings and README prose), 17 (a stated remedy changed) raised.

Verdict: APPROVE WITH NITS

Summary: Critical: 0 · High: 0 · Medium: 1 · Low: 1 · Lenses run: 19/19 (examined: 8; N/A: 11)

Prior context fetched: followup-fetch.sh exited 0 (6 of 6 files). The since boundary is 5e5f3f6cdf709aaa4a962ace1e2b75ac88f2a830.

Scope change: NO. The delta is prose and docstrings only, in files already in the review surface.

Security deep-dive: not run. No attack-surface trigger fired on this diff, which the round label records as the deferral.

Prior findings status

  • Round 1 #1 [Medium] The rig's local runtime fails the smoke gate on x2text-service → RESOLVED (closed in round 2). The README and docstring still name the uncomment remedy at tests/README.md:204 and tests/rig/runtime.py:319-322.
  • Round 2 #1 [Medium] "Add the e2e overlay" changes far more than x2text's port → RESOLVED in 39e34d9. The overlay alternative is gone from tests/README.md:204 and tests/rig/runtime.py:322.
  • Round 2 #2 [Low] The from_env docstring said the defaults match the dev compose stack → RESOLVED for what it raised, in 39e34d9. tests/rig/runtime.py:140-142 now says that runner and x2text-service are not published. The replacement text has its own gap, filed as new finding 2.
  • Round 1 unanchored item (lens 1, PR body did not cover the local runtime) → RESOLVED (closed in round 2).
  • Round 1 unanchored item (lens 13, CI e2e not yet run) → NOT RESOLVED. e2e is still skipping on the draft. Confirm it is green after the PR is marked ready.

New findings

  1. [Medium] [Lens 3 / 16 / 17]: the recreate command fails without VERSION. Posted inline at tests/README.md:204; the same command is at docs/local-dev-setup-executor-migration.md:213.
  2. [Low] [Lens 16]: the from_env exception list omits prompt-service. Posted inline at tests/rig/runtime.py:140-142.

Unanchored findings

  • [Low] [Lens 1] lint-pr fails: the PR has no backport label. The check reads: "no backport label: add fix/needs-backport to copy it to release lines, or main-only to keep it on main" (run 42193740682). The title passes. Which label applies is the author's call, and it must be set before merge.
  • CI e2e is still pending (carried over from round 1; see Prior findings status).

Lens checklist

  1. Spec & intent: Clean. The delta delivers what round 2 asked for, and the title follows TICKET [TYPE] text. The backport label is missing; see Unanchored findings.
  2. Architectural fit & precedent: Clean. Keeping only the uncomment remedy matches the runner precedent from #2442.
  3. Correctness & edge cases: See findings #1.
  4. Security: Clean (orchestrator). The delta is prose only. Boundary sweep: N/A, because no log line, error path, outbound client or endpoint changed.
  5. Data integrity & migrations: N/A (orchestrator). No data or schema changes.
  6. Concurrency: N/A (orchestrator). No concurrency code.
  7. API & contract compatibility: N/A (orchestrator). No wire format changed in the delta, and the round-1 consumer search still holds.
  8. Reliability & resilience: N/A (orchestrator). No runtime code changes.
  9. Performance & cost: N/A. Docs only.
  10. Observability: N/A. No logs or metrics changed.
  11. Operational safety: N/A (orchestrator). The delta does not touch compose or other config, and the round-1 assessment of the compose change stands.
  12. LLM/agent-specific: N/A. No model, prompt or tool changes.
  13. Testing: Clean (pr-test-analyzer). No test logic changed. tests/rig/tests/test_runtime.py passed 15/15 with no external dependencies needed. CI e2e is still pending.
  14. Dependencies & build: N/A (orchestrator). No dependency changes.
  15. Code quality: Clean. Pinned gate: pre-commit.ci - pr passed at 39e34d9. I did not run local tools at the pinned versions.
  16. Doc & comment accuracy: See findings #1, #2.
  17. Cross-document rule consistency: See findings #1. I swept the repo by hand for the recreate command and found it at tests/README.md:204, docs/local-dev-setup-executor-migration.md:213 and the run-platform.sh:324 hint. The merge-sweep script did not run, because the diff defines no identifiers to sweep for.
  18. On-prem deployment experience: N/A (orchestrator). No Helm chart, on-prem values or on-prem docs are touched.
  19. Scaling & workload lifecycle: N/A (orchestrator). No scaling or lifecycle values changed.

Where each line came from: code-reviewer gave lenses 1, 2, 3, 9, 10 and 15 (content), comment-analyzer gave 16, and pr-test-analyzer gave 13. The orchestrator assessed all the others, the lint-pr item and lens 15's pinned gate. Findings 1 and 2 were also reached independently by the orchestrator.

Open questions / assumptions

  • Should the run-platform.sh:324 restart hint and the runner half of the docs line get the VERSION prefix in this PR, or in a follow-up?
  • Assumption: the pre-commit.ci pass covers the delta files at the pinned hook versions.

cost: agents=3 wall=06:19 lenses-examined=8 of 19 files=6 lines=28

Comment thread tests/README.md Resolved
Comment thread tests/rig/runtime.py Resolved
…port

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Standardized review: round 4, review-deep (attack-surface deferral), tip 281a022

Mode: FOLLOWUP. Whole-PR diff: git diff 86a63b848923baaff183280609bb5ca878471e63 HEAD (merge base with a freshly fetched origin/main; 6 files, 28 lines; file count matches GitHub). Round delta: git diff 39e34d953 281a022e7, covering tests/README.md (the local runtime row), the from_env docstring in tests/rig/runtime.py, and docs/local-dev-setup-executor-migration.md:213. Plugin: unstract v2.1.80.

Signals: lenses 13 (tests path changed), 16 (docstring and README/docs prose), 17 (a stated remedy changed) raised.

Verdict: APPROVE WITH NITS

Summary: Critical: 0 · High: 0 · Medium: 1 · Low: 1 · Lenses run: 19/19 (examined: 8; N/A: 11)

Prior context fetched: followup-fetch.sh exited 0 (6 of 6 files). The since boundary is 39e34d9539acb05623f0a04428a6cf90bc618610.

Scope change: NO. The delta is prose and one docstring, in files already in the review surface.

Security deep-dive: not run. No attack-surface trigger fired on this diff, which the round label records as the deferral.

Prior findings status

  • Round 3 #1 [Medium] The recreate command fails without VERSION → PARTIALLY RESOLVED in 281a022. At tests/README.md:204 it is resolved: that row's reader started the stack with ./run-platform.sh from the repo root, and re-running it sets VERSION (run-platform.sh:305, default latest at :350) and recreates the changed container. At docs/local-dev-setup-executor-migration.md:213 the same replacement does not fit that document; the residual is new finding 1.
  • Round 3 #2 [Low] The from_env exception list omits prompt-service → RESOLVED in 281a022. tests/rig/runtime.py:140-142 no longer lists exceptions; "Not every one is published" is true. (Its pointer to the commented-out ports entries offers no remedy for the prompt-service default, which has no service in that compose file; not re-raised, since the sentence is not wrong.)
  • Round 1 unanchored item (lens 13, CI e2e not yet run) → NOT RESOLVED. e2e is still skipping on the draft at 281a022.

New findings

  1. [Medium] [Lens 16 / 3 / 17] — The executor-migration doc now says to re-run ./run-platform.sh, a script that doc never uses to start the stack

    • Location: docs/local-dev-setup-executor-migration.md:213
    • Failure mode: this document builds images with docker compose -f docker-compose.build.yaml build (§2.3, L93-102) and starts the stack with docker compose [--profile workers-v2] up -d from docker/ (§4.2, L175-187), so its reader has supplied VERSION themselves. ./run-platform.sh overrides that with VERSION=latest and runs up -d over the stack (run-platform.sh:305, :350). A reader whose branch builds carry any other tag gets every changed container recreated on :latest (pulled if absent), i.e. not the feature-branch build the doc is about, with nothing saying so. Also, the block just above ends in workers/ (L205), so a literal ./run-platform.sh there is "no such file".
    • Evidence: the round-3 text (docker compose up -d runner x2text-service from docker/) matched this document's workflow; the round-3 finding's root cause (unset VERSION) was specific to the tests/README.md reader, who starts via run-platform.sh.
    • Suggested fix: in this document only, go back to the compose form it already uses and name the directory and tag, e.g. "from docker/, run VERSION=<the tag you built> docker compose up -d runner x2text-service". Keep the run-platform.sh wording in tests/README.md.
    • Confidence: High for the mismatch and the working directory; Medium for the tag swap, which needs a non-latest local tag.
    • Verification: VERIFIED by reading run-platform.sh:157-305,346-370 and the doc's §2.3-§4.4. The tag swap is UNVERIFIED by execution: would VERSION=dev builds, then a plain ./run-platform.sh, show docker inspect unstract-backend --format '{{.Config.Image}}' as :latest?
  2. [Low] [Lens 16] — "Re-run ./run-platform.sh" drops any -v <tag> the stack was started with

    • Location: tests/README.md:204
    • A stack started with ./run-platform.sh -v vX.Y.Z is recreated on latest by a plain re-run (run-platform.sh:305, :350), so the local e2e run then tests a different version. Suggested fix: "re-run ./run-platform.sh with the same options you started it with". (A -b local build is unaffected: it is tagged latest, and a re-run pulls only on first setup or -u, run-platform.sh:281.)

Unanchored findings

  • [Low] [Lens 1] The PR body is stale on the local runtime. It still says the local runtime "needs the loopback mapping uncommented or the e2e overlay added"; round 3 dropped the overlay alternative from tests/README.md and tests/rig/runtime.py, and round 4 changed the recreate step to re-running run-platform.sh.
  • CI e2e is still skipping (carried over; see Prior findings status). The lint-pr backport-label failure is known and left to the author.

Lens checklist

  1. Spec & intent: Clean. The delta delivers what round 3 asked for at tests/README.md; the title follows TICKET [TYPE] text. PR-body staleness is under Unanchored findings.
  2. Architectural fit & precedent: Clean. The uncomment-and-recreate remedy matches the runner precedent from #2442.
  3. Correctness & edge cases: See findings #1.
  4. Security: Clean (orchestrator). The delta is prose only. Boundary sweep: N/A, no log line, error path, outbound client or endpoint changed.
  5. Data integrity & migrations: N/A (orchestrator). No data or schema changes.
  6. Concurrency: N/A (orchestrator). No concurrency code.
  7. API & contract compatibility: N/A (orchestrator). No wire format changed in the delta; the round-1 consumer search still holds.
  8. Reliability & resilience: N/A (orchestrator). No runtime code changes.
  9. Performance & cost: N/A. Docs only.
  10. Observability: N/A. No logs or metrics changed.
  11. Operational safety: N/A (orchestrator). The delta does not touch compose or other config; the round-1 assessment of the compose change stands.
  12. LLM/agent-specific: N/A. No model, prompt or tool changes.
  13. Testing: Clean (orchestrator). The only code-file change is a docstring; no test logic changed. CI e2e still pending.
  14. Dependencies & build: N/A (orchestrator). No dependency changes.
  15. Code quality: Clean. Pinned gate: pre-commit.ci - pr passed at 281a022. I did not run local tools at the pinned versions.
  16. Doc & comment accuracy: See findings #1, #2.
  17. Cross-document rule consistency: See findings #1. Swept by hand for the recreate instruction: tests/README.md:204, docs/local-dev-setup-executor-migration.md:213 and the run-platform.sh:324 restart hint. The merge-sweep script did not run, because the diff defines no identifiers to sweep for.
  18. On-prem deployment experience: N/A (orchestrator). No Helm chart, on-prem values or on-prem docs are touched.
  19. Scaling & workload lifecycle: N/A (orchestrator). No scaling or lifecycle values changed.

Where each line came from: code-reviewer gave lenses 1, 2, 3, 9, 10 and 15 (content); comment-analyzer gave 16. The orchestrator assessed all others, the PR-body item and lens 15's pinned gate. Finding 1 was reached independently by both agents and the orchestrator. comment-analyzer rated finding 2 Medium on the premise that a re-run pulls registry :latest over -b builds; run-platform.sh:281 pulls only on first setup or -u, so it is rated Low here.

Open questions / assumptions

  • Assumption: readers of the executor-migration doc may tag local builds other than latest; if that doc assumes latest, finding 1 reduces to the working-directory and wrong-workflow issue.

cost: agents=2 wall=05:06 lenses-examined=8 of 19 files=6 lines=28

Comment thread tests/README.md Resolved
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Nov 6, 2026

Copy link
Copy Markdown

@ritwik-g ritwik-g left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Standardized review: round 5, review-deep (attack-surface deferral), tip 7edb91a

Mode: FOLLOWUP. Whole-PR diff: git diff 86a63b848923baaff183280609bb5ca878471e63 HEAD (merge base with a freshly fetched origin/main; 6 files, 28 lines; file count matches GitHub). Round delta: git diff 281a022e7 7edb91ad3, one sentence each in tests/README.md:204 and docs/local-dev-setup-executor-migration.md:213, plus a PR-body edit. Plugin: unstract v2.1.80.

Signals: lenses 13 (tests path changed), 16 (README/docs prose), 17 (a stated remedy changed) raised.

Verdict: APPROVE WITH NITS

Summary: Critical: 0 · High: 0 · Medium: 0 · Low: 1 · Lenses run: 19/19 (examined: 8; N/A: 11)

Prior context fetched: prior findings reconstructed from my own review threads on this PR (rounds 1-4); since boundary 281a022e707a9b6f7dc0ace3934637270c63766d.

Scope change: NO. The delta is prose in files already in the review surface.

Security deep-dive: not run. No attack-surface trigger fired on this diff, which the round label records as the deferral.

Prior findings status

  • Round 4 #1 [Medium] The executor-migration doc said to re-run ./run-platform.sh, a script that doc never uses → RESOLVED in 7edb91a. docs/local-dev-setup-executor-migration.md:213 now says to recreate from docker/ with VERSION=<tag> docker compose up -d runner x2text-service. That resolves the same compose file and project as run-platform.sh:302-305, neither service is in a profile, and adding ports is a config change, so up -d recreates both.
  • Round 4 #2 [Low] A plain re-run drops -v <tag> → RESOLVED in 7edb91a for the -v case. The wording that replaced it, which this review suggested in round 4, raises a new Low (finding 1 below).
  • Round 3 #1 [Medium] The recreate command failed without VERSION (was PARTIALLY RESOLVED) → RESOLVED in 7edb91a; the remaining location, the doc's L213, now sets VERSION.
  • Round 4 unanchored [Low] PR body stale on the local runtime → RESOLVED. The "or the e2e overlay added" alternative is gone from the body.
  • Round 1 unanchored item (lens 13, CI e2e not yet run) → NOT RESOLVED. e2e is still skipping on the draft at 7edb91a.

New findings

  1. [Low] [Lens 16 / 3] — "Re-run ./run-platform.sh with the options you started it with" does more than recreate x2text when those options include -u (or -b) — inline at tests/README.md:204.

Unanchored findings

  • CI e2e is still skipping (carried over; see Prior findings status). The lint-pr backport-label failure is known and left to the author.

Lens checklist

  1. Spec & intent: Clean. The delta delivers both round-4 fixes; the title follows TICKET [TYPE] text. (Nit, not tallied: the body's local runtime bullet says tests/rig/runtime.py "now say[s] so" about uncommenting and re-running; the docstring at tests/rig/runtime.py:320-322 names only the uncomment step. The README carries the full step.)
  2. Architectural fit & precedent: Clean. The two files now give different recreate commands, which is deliberate: each one matches how its own reader starts the stack (round 4).
  3. Correctness & edge cases: See findings #1.
  4. Security: Clean (orchestrator). The delta is prose only. Boundary sweep: N/A, no log line, error path, outbound client or endpoint changed.
  5. Data integrity & migrations: N/A (orchestrator). No data or schema changes.
  6. Concurrency: N/A (orchestrator). No concurrency code.
  7. API & contract compatibility: N/A (orchestrator). No wire format changed in the delta; the round-1 consumer search still holds.
  8. Reliability & resilience: N/A (orchestrator). No runtime code changes.
  9. Performance & cost: N/A. Docs only.
  10. Observability: N/A. No logs or metrics changed.
  11. Operational safety: N/A (orchestrator). The delta does not touch compose or other config; the round-1 assessment of the compose change stands.
  12. LLM/agent-specific: N/A. No model, prompt or tool changes.
  13. Testing: Clean (orchestrator). No test logic changed in the delta. CI e2e is still pending.
  14. Dependencies & build: N/A (orchestrator). No dependency changes.
  15. Code quality: Clean. Pinned gate: pre-commit.ci - pr passed at 7edb91a. I did not run local tools at the pinned versions.
  16. Doc & comment accuracy: See findings #1.
  17. Cross-document rule consistency: Clean. I swept the recreate instruction by hand: tests/README.md:204, docs/local-dev-setup-executor-migration.md:213, the tests/rig/runtime.py:320-322 docstring, the workers/sample.env comments and the run-platform.sh:323-324 restart hint. None contradicts another; they differ only in how much each says. The merge-sweep script did not run, because the diff defines no identifiers to sweep for.
  18. On-prem deployment experience: N/A (orchestrator). No Helm chart, on-prem values or on-prem docs are touched.
  19. Scaling & workload lifecycle: N/A (orchestrator). No scaling or lifecycle values changed.

Where each line came from: code-reviewer gave lenses 1, 2, 3, 9, 10 and 15 (content); comment-analyzer gave 16. The orchestrator assessed all others, the PR-body nit and lens 15's pinned gate. comment-analyzer also noted that the doc's own §4.2 start commands (L178, L187) never set VERSION, and that docker/sample.env does not define it. So "the same tag you started the stack with" assumes the reader exported VERSION. That gap is in text this PR does not touch, and L213 is accurate, so it is not raised as a finding.

Open questions / assumptions

  • Assumption: readers of the executor-migration doc export VERSION in their shell, because its build and start commands only work if they do.

cost: agents=2 wall=04:16 lenses-examined=8 of 19 files=6 lines=28

Comment thread tests/README.md Resolved
@ritwik-g
ritwik-g marked this pull request as ready for review November 6, 2026 09:41
@greptile-apps

greptile-apps Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

via Greptile

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge.

Summary

Stops publishing x2text-service on the host by default.

  • The x2text service stays on the Compose network unless host access is needed.

ritwik-g explicitly identifies host access as opt-in. Host-run workers, the backend, and local tests must enable the loopback mapping; that change is intentional.

Reviews (1) · Last reviewed commit: "docs: give each recreate instruction the..." · Reviewed by Greptile

@ritwik-g
ritwik-g requested a review from athul-rs November 6, 2026 09:44
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Unstract test results

Per-group results

Status Group Tier Passed Failed Errors Skipped Duration (s)
⚪ e2e-agent-kv e2e 0 0 0 1 0.1
✅ e2e-api-deployment e2e 3 0 0 0 11.8
✅ e2e-coowners e2e 1 0 0 0 1.0
✅ e2e-etl e2e 1 0 0 0 8.0
✅ e2e-login e2e 2 0 0 0 1.0
✅ e2e-prompt-studio e2e 1 0 0 0 12.5
✅ e2e-smoke e2e 2 0 0 0 0.8
✅ e2e-workflow e2e 1 0 0 0 12.1
✅ frontend unit 664 0 0 0 14.0
✅ frontend-v1-unit unit 284 0 0 0 5.1
✅ integration-backend integration 1557 0 0 26 90.9
✅ integration-connectors integration 1 0 0 7 9.8
✅ integration-workers integration 181 0 0 1 58.2
❌ ui e2e 0 1 0 0 0.0
✅ unit-agent-kv-schema unit 143 0 0 0 1.3
✅ unit-backend unit 2159 0 0 1 47.5
✅ unit-connectors unit 82 0 0 0 8.7
✅ unit-core unit 289 0 0 0 2.5
✅ unit-filesystem unit 1 0 0 0 4.7
✅ unit-platform-service unit 22 0 0 0 2.2
✅ unit-rig unit 139 0 0 0 4.3
✅ unit-runner unit 12 0 0 0 2.2
✅ unit-sdk1 unit 1356 0 0 0 34.7
✅ unit-tool-sidecar unit 8 0 0 0 1.5
✅ unit-workers unit 1675 0 0 2 116.4
✅ unit-x2text-service unit 116 0 0 0 3.2
TOTAL 8700 1 0 38 454.7

Critical paths

⚠️ Critical paths not yet covered

  • workflow-execution-fan-out — Multi-file workflow execution fans out to file-processing workers and rejoins. (declared coverage: no groups declared)
✅ Covered critical paths
  • auth-login — covered by e2e-login
  • adapter-register-llm — covered by integration-backend
  • workflow-author — covered by integration-backend
  • co-owner-manage — covered by integration-backend, e2e-coowners
  • workflow-create-execute — covered by e2e-workflow
  • api-deployment-provision — covered by integration-backend
  • api-deployment-auth — covered by integration-backend
  • api-deployment-run — covered by e2e-api-deployment
  • mcp-server-auth — covered by integration-backend
  • mcp-platform-auth — covered by integration-backend
  • platform-key-whoami — covered by integration-backend
  • prompt-studio-author — covered by integration-backend
  • prompt-studio-fetch-response — covered by e2e-prompt-studio
  • connector-register-test — covered by integration-backend
  • pipeline-etl-execute — covered by e2e-etl
  • usage-aggregate-read — covered by integration-backend
  • usage-token-tracking — covered by e2e-api-deployment
  • callback-result-delivery — covered by e2e-api-deployment

@athul-rs athul-rs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Quick pass on 7edb91ad3. The change is right: backend and workers reach x2text as unstract-x2text-service:3004 on the compose network, the e2e overlay keeps the rig's host-side probe working, and nothing else on main (run-platform.sh, sample.compose.override.yaml, CI) dials localhost:3004. Two items:

  1. lint-pr is red: the PR has no backport label. The check now requires one label on every PR into main (no backport label: add fix/needs-backport to copy it to release lines, or main-only to keep it on main). #2442, the runner change, carries fix/needs-backport. The same label fits here, so the two ports close together on the release lines. Use fix/security instead if this should also reach lines already released.
  2. Nit: the "x2text must be reachable at UNSTRACT_X2TEXT_URL" note sits in the TestcontainersRuntime docstring (tests/rig/runtime.py:320). LocalRuntime (runtime.py:169) is the runtime it applies to, and its docstring still says only "collect endpoints from env". A one-line pointer there would put the note where a reader of --runtime local looks. Optional.

@ritwik-g ritwik-g added the main-only Stays on main: not backported to a release line label Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

main-only Stays on main: not backported to a release line

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants