Skip to content

Three fixes the live skill passes found - #42

Closed
fiharet34 wants to merge 13 commits into
joomcode:mainfrom
fiharet34:fix/category-opportunity-index-language
Closed

fiharet34 wants to merge 13 commits into
joomcode:mainfrom
fiharet34:fix/category-opportunity-index-language

Conversation

@fiharet34

Copy link
Copy Markdown
Contributor

Three corrections that came out of running the skills end to end against live market data.

  • seller-overview-tracker — the store overview
  • top-brand-position-tracker — brand ranking
  • top-sellers-in-category — seller leaderboard

This commit was pinned by the parent portal repository but existed on no remote, so a
fresh git clone --recurse-submodules of the portal failed with
upload-pack: not our ref. Pushing it makes the portal buildable by anyone other than
its author; merging it here lets the parent re-pin to main rather than to a topic
branch.

Separate from the open drafts #35–41, which are different fix branches.

🤖 Generated with Claude Code

fiharet34 and others added 13 commits September 8, 2026 11:43
…g buy-box position as idle stock

Checks each estimate against the seller's real completed sales before placing a
row: shops with no real trading history move out of the ranking into a labelled
group, while a real business whose estimate runs high stays in with a caveat.
Groups shops sharing a name stem and says whether that changes the leader,
without asserting common ownership.

Reframes the registered-versus-with-sales comparison as sellers only. On a
catalog product only the buy-box holder shows sales, so the product gap measures
buy-box position rather than idle inventory - and since the panel now renders
every run, an unlabelled version of that chart would mislead every time.

Also: medal as a column so the saved baseline can reproduce its own panel, the
growth column named for the metric it carries, full money precision in a
ranking, a missing-value rule, a width fallback that drops columns rather than
the table, retry after a pause, and an empty result separated from an outage.
…lt on, and stop the floor moving between runs

The skill ranked niches by month-over-month growth and was forbidden from
displaying it - Output said "exactly these five columns ... not a displayed
column" while Presentation rules prescribed a header for that column and the
panel required the growth figure on a card. On a text surface it appeared
nowhere: one run showed fifteen rows with the leader called "o maior salto" and
no percentage anywhere. Both growth columns are now displayed.

The size floor was invented per run. Two runs on one category, minutes apart,
chose R$ 1.000.000 and R$ 300.000, and the second run's leader sat below the
first run's floor - so the same question returned a different top niche. The
floor is now the greater of R$ 300 mil and 0,02% of the parent category's
estimated monthly revenue, which is stated in the output. A fixed figure cannot
serve both marketplaces: Mercado Livre ranks deep leaf niches, Shopee ranks
whole level-3 categories.

Also: revenue and unit growth read together, since a niche can grow revenue
while selling fewer units; concentration and revenue per seller as columns, and
seasonality as a Mercado Livre reading only, because Shopee carries none;
identifier-based navigation on both marketplaces, replacing a per-category link
that does not resolve; full money precision on Mercado Livre with Shopee exempt,
its figures being rebuilt from rounded counters; exact coverage counts; a
category-specific disclaimer with the monthly lag; retry after a pause; and an
empty result separated from an outage.
…ill's own language rule

The skill tells the model to detect the seller's language and respond in it, then
supplies the report step as (pt-BR) and the badge, indicators table and disclaimer
as Portuguese literals. Asked in English against the live connector, it returned an
entirely Portuguese report: the concrete literals win over the language rule.

- drop (pt-BR) from the Step 4 heading, which contradicted the Language rule
- say the badge and table labels are a template to translate, keeping the
  structure, the emoji and the R$ money formatting
- tell the disclaimer which half of its 'pt-BR / English' pair to emit

Behaviour for pt-BR sellers is unchanged.
Every skill carries the rule "detect the seller's language and respond in it.
Default to pt-BR". In a seller portal that reads as the *store's* language: the
store is Brazilian, its listings are Portuguese, and the model resolves "the
seller's language" to pt-BR no matter what language the seller typed. Asked in
English against the live connector, category-opportunity-index returned an
entirely Portuguese report while the assistant's own prose stayed English —
the skill was followed correctly, the instruction was ambiguous.

The previous commit on this branch blamed the pt-BR literals in the report
template. That diagnosis was wrong: with an explicit "write in English" the
same template rendered fully in English, so the literals never dominated. The
rule's wording was the whole defect.

- restate the Language rule in all 18 skills: write in the language of the
  message being answered, default pt-BR only when unclear, and never infer the
  language from the store, its listings or the marketplace
- point the "Respond in the seller's language" lines at the seller's request
- category-opportunity-index: say at the report step that the pt-BR wording is
  a template, and label 'alto/medio/baixo' and 'resumo' as pt-BR wording
- my-product-vs-catalog, new-growing-products-in-category, seller-overview-
  tracker, top-brand-position-tracker: drop the remaining pt-BR pins and say
  the headers and labels are a template to translate

Verified against the live JoomPulse connector: an English question to
category-opportunity-index and to top-keywords-in-my-category now returns an
English report with R$ and pt-BR number formatting intact, and the same
question in Portuguese still returns the pt-BR report unchanged.
Four skills present a downloadable `.csv` / `.xlsx` as part of the deliverable
without saying what to do where the client cannot write files. In a portal-style
host — a web UI whose agent has a fixed tool surface and no file output — the
skill duly offers a download that never arrives, and for the three trackers that
offer is load-bearing: they ask the seller to bring the file back next period as
the baseline.

The skills already hedge this way for visuals ("if no visual surface is available
at all, fall back to the markdown table"), so this applies the same shape to
files: offer the download where the client can produce files, and otherwise let
the markdown table stand as the deliverable rather than promising a file. The
trackers already accept a pasted table as the baseline, so nothing is lost.

- category-monitor, top-brand-position-tracker, top-sellers-in-category: make
  the download conditional and say the table stands on its own without it
- ml-product-analysis: same for the analogs spreadsheet; the `.csv` mentions in
  its input routing are untouched, since those describe what the seller supplies

No change where files are available.
The note added earlier — "the labels below are a template, not literal strings" —
does not work on its own. Tested against the live connector, an English question
to top-sellers-in-category came back with English prose over a wholly Portuguese
table: `Vendedor`, `Receita est.`, `Ticket médio`, values `ouro` / `sim`, and a
pt-BR disclaimer. The model reads a descriptive note as background and the column
spec as the thing to reproduce.

What did work, in category-opportunity-index, was the checkable sentence at the
end of its report step: when the request is in English, no Portuguese is left
anywhere. Every copy of the note now carries that sentence, and names the row
values and the disclaimer rather than only the headers, since those are what
leaked.

Retested afterwards: the same question returns `Seller`, `Est. revenue (1m)`,
`Avg. ticket`, values `platinum` / `yes`, and the English disclaimer, with `R$`
and the pt-BR number formatting intact.

- add the note to category-monitor, ml-product-analysis and
  top-sellers-in-category, which show pt-BR tables and had none
- unify the wording across all eight skills that carry it
Nine skills still had pt-BR headers, row values or disclaimers with nothing
telling the model to translate them, so an English question got English prose
over a Portuguese table whenever the model did not translate of its own accord.

top-keywords-in-my-category is the clearest case, and it ships: it said "the
headers below are the pt-BR default and may be rendered in the language of the
seller's request". That is permission, not an instruction. It happened to
translate under test, which is luck rather than behaviour -- the same wording
shape failed outright in top-sellers-in-category until the note was added there.

Every skill with pt-BR labels now carries the same note, ending in the checkable
sentence that made the difference: when the request is in English, no Portuguese
is left anywhere in the answer. Seventeen of the eighteen carry it;
pulse-find-exact-same-product has no pt-BR labels and needs none.

Retested against the live connector: an English question to
top-keywords-in-my-category now returns Position / Keyword / Products (supply)
with no Portuguese anywhere, and the keywords themselves stay in Portuguese,
which is right -- they are real Brazilian search terms.
An audit of all eighteen skills found two the earlier pass missed.
product-change-monitor offers a downloadable spreadsheet of the change table,
and seller-overview-tracker offers one twice, neither with a fallback for a
client that cannot write files.

seller-overview-tracker is the one that matters: like the other trackers, the
file is load-bearing there. It tells the seller to save the table and bring it
back next period as the baseline, so on a host with no file output the seller is
promised the mechanism the whole skill depends on and never gets it. Those
trackers already accept a pasted table, so nothing is lost by saying so.

Same shape as the other four: offer the download where the client can produce
files, and otherwise let the markdown table stand as the deliverable.
seller-copilot states its conventions as a bullet list rather than the
**Language:** heading the other skills use, so the earlier sweep passed over it.
Its bullet already named the request rather than the seller, which is the
ambiguity that caused the bug, but it lacked the two clauses that made the fix
hold elsewhere: that the language is never inferred from the store or its
listings, and that an English request leaves no Portuguese in the answer.

Extended in its own bullet style rather than pasting the block the other skills
carry, since this skill is a conventions document and not a report template.
Running the pack against the real connector surfaced these; every one was
re-run afterwards and the fix confirmed.

top-keywords-in-my-category: drop the "Produtos (oferta)" column. The cube's
own schema marks the only field that could fill it as unreliable and says not
to surface it, so the column was always "—". Say no such count exists and
forbid a substitute, or the next model invents a volume metric to fill the gap.

ml-product-analysis: every analog row carries its links. The rule was already
there and was ignored, so it now says what an incomplete row looks like. Also
name the sort key in the answer: "demand" here means estimated revenue, and the
sales column beside it will not descend with it.

uncontested-niche-finder: run the incumbent check over every listing in the
sub-category, not the set already narrowed to listings with sales, and state
how many listings it covered. A category with a dormant platinum seller was
being reported as uncontested, and the count is what makes the claim auditable.

high-demand-low-quality-finder: cap the table at twelve rows and say how many
matched. At twenty-five rows of fifteen columns the answer ran past the host's
output limit and was cut mid-row, taking the disclaimer with it.

top-sellers-in-category: label the two store-wide columns as store-wide. The
365-day sales and cancellation figures cover the whole store while every other
column is category-scoped, so a reader compared a monthly category figure with
a yearly store-wide one and concluded the category had collapsed.
The portal was pinned to a 20 August baseline of this skill, so the manual pass
flagged the missing ranking figure and then withdrew it against text that said
never present a change. joomcode#36 is that fix, already open upstream.
Takes joomcode#35 whole for this skill — it is more thorough than the store-wide fix
made here today. It finds five store-wide fields where that found two, adding
monthly growth, international shipping and the listing-type counts, and it
explains why the listing-type counts do not add up to the category product
count.

Two things from this branch are re-applied on top, both because a live run
showed the difference:

The store-wide columns say so in the header. joomcode#35 states the scope in prose
("say which figures are category-scoped and which are store-wide"), and that is
the form that did not hold: a leaderboard still put a monthly category figure
beside a yearly store-wide one with nothing marking them apart, and a reader
would conclude the category had collapsed. The header label survived where the
prose did not, so both are kept and all six store-wide columns now carry it.

The download offer stays conditional. joomcode#35 predates that fix and promises a
`.csv` / `.xlsx` in six places; no host is guaranteed to write files, and this
portal cannot, so it would promise a download that never arrives and the
trackers depend on that file being the baseline.
- top-sellers-in-category: every seller ranked is a row of one markdown
  table -- never a numbered list, never leaders-in-table with the rest in
  prose, because the user saves this table and pastes it back next period.
  The Vendedor name is plain text: sellers have no JoomPulse dashboard
  page, so a URL built from a shopId 404s. Also restores PR joomcode#37's language
  wording, which the local merge of joomcode#35 resolved away.

- seller-overview-tracker: the monthly sales trend is the change in
  JoomPulse's estimated sales, not real Mercado Livre data, so it carries
  the estimate caveat and never appears among the real figures. No seller
  link, for the same reason as above.

- top-brand-position-tracker: a category has no JoomPulse page either, so
  the table carries no category link.

Not pushed, and no PR for the table-shape rule: joomcode#35 rewrites the same
region of that file, so a PR now would mean resolving the same conflict
twice.
@fiharet34

Copy link
Copy Markdown
Contributor Author

Closing: this branch carries 13 commits, including local merges of #35 and #36 and the content of the still-open drafts #37, #38, #40 and #41. Merging it would land work that is under review elsewhere. Reopening with only the three live-pass fixes on top of main.

@fiharet34 fiharet34 closed this Sep 14, 2026
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