fix(gst): bind a GSTR-2B refusal to the period on screen - #355
fix(gst): bind a GSTR-2B refusal to the period on screen#355lamemustafa wants to merge 14 commits into
Conversation
The summary route does not change per period and keeps rendering whichever period it last loaded, so a refusal read without its header answered for every later period in a fiscal-year run. One live run reported twelve periods processed after a single navigation, while the page still read April. For a taxpayer with a statement in some months and not others, that silently marks drafted months as absent and skips their downloads. The refusal is now recorded only when the visible header confirms the requested period, and the guard fails closed: an unreadable header is could not determine, never matches. A page showing some other period is left rather than answered for. Both the refusal branch and the download-ready branch asked that same question in the same six lines, so it has a name now. Registering the page-identity signals is the other half. They were transient while the only step carrying them was the ready hand-off, whose signals never reach durable state; recording the refusal made them terminal. One unregistered token rejects the whole array, so every period the portal declined was stored as needing review instead.
The transient ready step carried an unregistered token harmlessly for months, so the guard asserts the property that actually matters: a step whose signals get persisted must produce signals the durable parser accepts.
Both pause reasons can render at once, and unlabelled they read as one contradictory statement: a live run showed could not start a full fiscal year run, the all-year plan's reason, directly above a single-return run that had started and processed twelve periods.
The single-return fiscal-year path maps a target status to an outcome through an exhaustive record, so a status it has not been told about fails to compile. The all-returns path kept two hand-written copies of that mapping, each ending in a needs-review default that silently absorbed one. A period the portal declined to generate therefore read as resolved in one run type and as needing a person in the other, and a run of everything stopped on periods that could never change while the same year run for one return completed and exported its ZIP. Both copies now call the shared record.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0e6fe9e31d
ℹ️ 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".
Two review findings, both correct on the values and one over-broad on the route. A filing status read from a live authenticated page, and a statement that the taxpayer reports no e-invoices, are both facts about a return rather than about the portal. Neither is needed: the findings are that the detail route can carry the control, and that the portal returns an unavailable-workbook modal when a period has no e-invoice records. Both now state the portal's rule, with its own advisory quoted as the evidence for it. A third of the same class was not flagged and is gone too -- a period name quoted from the stale header. The finding is that the panel keeps rendering whichever period it last loaded, which does not need the period named. The route itself stays. It is already published in this file on master and exported from src/connectors/gst/portal-artifact-endpoints.ts as GSTR1_DETAIL_PATH, so it discloses nothing this repository does not already state, and the finding cannot be recorded without naming the surface it is about.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 708f12e4fe
ℹ️ 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".
`verifyVisibleGstr2bPeriod` accepted the page's own inline configuration in place of the header a reader can see. Two callers reach it and they are not alike: a download click may lean on that configuration, because the file it produces is correlated to the target before the target counts as complete; a refusal may not, because it resolves the target outright and no artifact follows to corroborate it. So an unlabelled refusal panel whose inline config happened to match resolved a period as not-generated and advanced a fiscal-year run, emitting `gstr2b-visible-period-verified` for an identity nothing visible confirmed. The refusal path now asks for visible evidence and the signal tells the truth. The branch ordering also collapses: complete labels or the statement heading pass, inline config passes only where it is allowed to.
Fails without the guard: the unlabelled panel records the period instead of leaving it.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a2316bdf9e
ℹ️ 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".
…d-outcome' into tapish-codex/gstr2b-refusal-period-binding
The post-click path inherits the binding from its base; this holds it to the stricter reading introduced here. A refusal resolves its target outright and no artifact follows to corroborate it, so the page's own inline configuration cannot stand in for a header a reader can see -- on either path. Both refusal paths now pass `requireVisibleEvidence`. The download path still does not, because its file is correlated to the target before the target counts.
Fails when the flag is dropped at that call site.
…efect The comment named how many periods one live run found unavailable, which is a fact about that taxpayer's returns rather than about the persistence bug it was explaining. The bug is that every declined period came back as needs-review; the count was never part of it.
…codex/gstr2b-refusal-period-binding The GSTR-1 findings entry existed on both sides. Kept the base's: it describes the control row structurally instead of reproducing captured portal copy, and it drops a sentence about the captured return's own filing state, which is a fact about a taxpayer rather than about the portal's surfaces. The sections below it are this branch's and are unaffected.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e881215e75
ℹ️ 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".
|
The corrected consolidated candidate is #359, based directly on master. This PR is retained as draft with its commits and review history intact; its unchanged head is not independently merge-ready. The #359 body maps every original automated ask to specific source/test evidence or an explicit held follow-up. Authenticated runtime qualification remains required before merging the replacement. |
|
Superseded by #359. Its disposition register records the final status of this draft’s review asks. This draft is being closed; resolving its remaining threads marks them superseded, not fixed on this unchanged branch. |
Summary
The GSTR-2B refusal is now bound to the period visible on screen, and the page-identity signals it
carries are registered as durable.
The summary route does not change per period and keeps rendering whichever period it last loaded. Read
without its header, one period's refusal answered for every later period: a live run reported twelve periods
processed after a single navigation, while the page still read April.
Root Cause / Decision Record
What failed, twice.
First, the refusal was recognised without checking the visible header. For a taxpayer with a statement in
some months and not others, that silently marks drafted months absent and skips their downloads — a
confident wrong answer rather than a stall.
Second, once the refusal was recorded the step became terminal, so its signals were persisted for the
first time. One of them had never been registered — it had only ever ridden a transient
readystep, whosesignals never reach durable state. One unregistered member rejects the entire array, so every period the
portal declined was stored as needing review instead.
Why this is the smallest safe fix. The guard already existed and already failed closed; it simply was not
consulted on this path. Both the refusal branch and the download-ready branch asked the same question in the
same six lines, so it now has a name. The signals are registered rather than suppressed, because they are the
evidence that the period was verified before the refusal was recorded.
Also here. Two hand-written status-to-outcome mappers in the all-returns path each ended in a
needs-reviewdefault, so the same period read as resolved in one run type and as needing a person in theother. Both now call the exhaustive record the single-return path already used.
Scope
docs/PORTAL_INTEGRATION_FINDINGS.md— the refusal panel outliving the period it was loaded for.Pack Workflow Preflight
pnpm workflow:preflightwas run before editing/push, or the skip reason is documented.Sanchika Adoption Gate
@sanchika/*packages or copied Sanchika guidance, Iread
sanchika/docs/adoption-pack.mdin the coordinated parent worktree.and records the Sanchika commit or copied guidance used.
../sanchika,sanchika/packages/*/src, or parentsource paths.
Privacy And Data-Flow Impact
Sensitive Surface Review
Target binding is intentionally strengthened: a portal refusal is recorded only when the visible header confirms the requested period, and an unreadable header fails closed to navigation rather than to a recorded outcome. Signals reaching durable state for the first time are registered, and a test asserts every terminal step's signals survive the durable parser.
Chrome Web Store Impact
docs/PUBLICATION_READINESS.mdis checked.Verification
pnpm install --frozen-lockfilepnpm audit --audit-level highpnpm exec wxt preparepnpm exec prettier --check .pnpm exec eslint . --max-warnings 0pnpm exec tsc --noEmitpnpm exec vitest runpnpm exec wxt buildnode scripts/verify-extension-package.mjs .output/chrome-mv3pnpm exec wxt zipnode scripts/verify-extension-zip.mjsnode scripts/write-release-provenance.mjsnode scripts/verify-github-release-assets.mjs --tag <tag> --zip <zip> --checksum <sha256> --provenance <json>when release assets existnode scripts/publish-chrome-web-store.mjs --zip .output/<zip> --provenance .output/pack-release-provenance.v1.json --publisher-id <id> --dry-run truegit diff --checkpnpm review:gate -- --strict-head-review --wait-head-review-ms 180000before merge/readiness claim; a missing Codex review blocks readiness:Artifact Evidence
No release artifact in this PR; it ships no ZIP and changes no release metadata.
Verification above was run on this branch in an isolated worktree, so the result is the branch's own and not
the stack tip's.
PR Review Follow-Up
708f12e— the filing status is removed (this file publishes no such value on master; count is zero), plus a third instance of the same class the review did not flag. The route is rejected with evidence:/returns/auth/gstr1is already published in this file on master alongside four other routes, and is exported asGSTR1_DETAIL_PATHinsrc/connectors/gst/portal-artifact-endpoints.ts:19. Reasoning on the thread.708f12e— the claim about the return is replaced by the portal's rule, with its own advisory quoted as the evidence for itScreenshots
Use synthetic data only.
Stacking
Stacked on #354 (
tapish-codex/gstr2b-not-generated-outcome), which is stacked on #353. Review inorder: 353, then 354, then this.