fix(gst): acquire filed GSTR-1 artifacts from the surfaces the portal offers - #353
fix(gst): acquire filed GSTR-1 artifacts from the surfaces the portal offers#353lamemustafa wants to merge 10 commits into
Conversation
… offers The filed GSTR-1 detail route can carry the download control itself, labelled DOWNLOAD FILED (PDF), with no View Summary control on the page. Navigating away from a page that already offered the download left the flow waiting until its step limit. Observer signals now read their control patterns from the return descriptors instead of restating them, so a label the descriptor learns about cannot stay unrecognised in the other layer. A live NIL GSTR-1 summary envelope is smaller than the minimum byte floor the validator applied, so a valid artifact was rejected as too small. The floor is removed and rejections name their own shape-based reason.
…rows A handler failure rendered one generic sentence for every cause, so three live sessions were spent guessing which throw it was. The fingerprint appends the error name and the first non-extension stack symbol, which is enough to identify the throw from the panel without DevTools. Redaction is the point of the charset filter: only name-shaped characters survive, so no message, path, URL, or portal value can reach the panel through it.
The diagnostics module claimed emitters and the durable allowlist read one list. They did not: emitters wrote string literals and only the allowlist imported it, so the coupling the comment described existed nowhere. An unregistered signal rejects the whole durable array, which is how a diagnostic built to explain a failure halted the run instead. Emitters now declare they return one of the listed signals, so a literal nobody registered fails to compile rather than failing at persistence. That is the level this class needs. Separately, five structures across three modules held the two portal refusals -- a signal set, a reason set, a map between them, and two allowlist entries -- with the artifact- prefix relating them stated nowhere. One list and one derivation now, so registering a third refusal is a single line.
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: babcedc25b
ℹ️ 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".
Three places treated "the console is not persisted" as a reason to log whatever arrived, and one treated a character class as proof a value was safe. **The background handler logged the raw error.** A rejection from storage, scripting, or downloads can quote a URL, a path, or a response body. The fingerprint carries what a reader needs and is established to be this bundle's own, so it is what gets logged. **The durable-signal boundary named the token it rejected.** That boundary exists precisely because it cannot know what it has been handed -- a legacy or malformed entry read back from storage is the input it is there to refuse -- so repeating it in a console sink undoes the refusal. The diagnostic it replaced was written when an unregistered signal could only be found at runtime; it no longer can, because the signal lists are types and a producer emitting an unregistered token fails to compile. **The fingerprint laundered its input.** `safeSymbol` stripped punctuation, so a stack frame pointing at a portal URL came back looking like a symbol precisely because the characters that would have exposed it were deleted. A filter that edits its input until it passes is worse than no filter: it manufactures the appearance of safety. A symbol is this bundle's because the frame it came from points at this bundle's own origin -- provenance, not shape. A name is kept when it is shaped like an error class, which every class here and in the platform is, and which cannot spell a GSTIN, an ARN, or a URL. Anything else degrades to `Error`.
**A declined dialog was not bound to the target that raised it.** The detail route does not change per period, so a dialog left standing by an earlier target would mark this artifact unavailable -- and a composite or full-year run would carry on having silently omitted an artifact the portal never declined for it. The guard that binds a download click already asks exactly the right question, so it is asked here too: recording a refusal resolves a target outright and no artifact follows to corroborate it, which is the same bar. **A View Summary step was skipped on a text-derived signal.** `download-filed-gstr-1` says the filed-PDF label appears somewhere on the page, which decoy or non-actionable copy also does. Skipping the real control on that basis strands a target whose PDF was reachable: acquisition then finds nothing to click and blocks it. Whether a page offers an artifact is a question about controls, so the page's controls are what get asked. The resolver that answers it moves next to the descriptor owning the label, so the two cannot drift apart, and `artifact-source` loses its private copy.
**Inspection failure replaced the acquisition failure.** The follow-up message runs after an acquisition has already failed and can only refine it. A tab that has closed, navigated, or refuses injection means the failure cannot be refined, not that a new one occurred -- but the unguarded call threw, replacing a specific actionable reason with the generic background error and losing the terminal summary with it. **A definitive refusal left its intent checkpoint standing.** The retain decision is made about an acquisition failure. When the portal's no-details answer replaces that failure, it is no longer one: nothing exists to download, so nothing is left for a retry to reconcile. The checkpoint survived anyway and blocked the next attempt as `artifact-acquisition-start-unreconciled` -- refusing the retry that very result offers. The nested ternary became an early return; the second fix has nowhere to live inside an expression.
The size cap is a processing bound, not only a verdict. A rejected oversized preflight body went straight into the diagnostic helper, which decoded and parsed all of it -- spending exactly the work the cap exists to refuse, on the one path where the input is known to be unreasonable. The band is the whole diagnostic here: nothing inside an oversized body would change what a reader does about it. The signal registers by derivation, so no allowlist needed telling.
Each fails with its guard removed. The fingerprint fixtures used invented `file.js` frames. A background stack points at this bundle's own origin on every line, which is what makes a symbol ours -- so a fixture that omitted it could not have caught a frame from anywhere else.
The change relied on a live 2026-09-10 capture that this repository had not recorded, while `LIVE_FILED_RETURNS_SPIKE.md` still stated the opposite from an earlier one: that the detail page never exposes the PDF and must be navigated through View Summary. Both captures are real. The detail route has two shapes, and the spike's paragraph was read as a general rule. A contradiction left standing is how a fix gets reimplemented from the stale half, so the spike entry is marked superseded in place -- it stays, because it is a dated record of what was seen -- and the finding goes where captures go.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9beb1aba59
ℹ️ 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
Three filed-GSTR-1 acquisition defects found in a live authorised run, plus a diagnostic that made the
next one findable in one round instead of three.
The filed GSTR-1 detail route can carry the download control itself, labelled
DOWNLOAD FILED (PDF),with no View Summary control anywhere on the page. Navigating away from a page that already offered the
download is what left the flow waiting until its step limit.
Observer signals now read their control patterns from the return descriptors instead of restating them.
This file carried its own copies, so a label the descriptor learned about stayed unrecognised here — which is
how one label was missed by both layers at once.
A live NIL GSTR-1 summary envelope is smaller than the minimum-byte floor the artifact validator applied,
so a valid artifact was rejected as too small. The floor is removed; rejections now name their own
shape-based reason instead of a size.
Root Cause / Decision Record
What failed. A NIL GSTR-1 period could not be acquired at all. Three independent causes, each of which
alone was enough: the flow navigated away from the page holding the control, the control's label was
unknown to the observer layer, and a valid small artifact failed a size floor.
Why this is the smallest safe fix. Each cause is corrected where the fact belongs — the descriptor owns
control labels, the endpoint map owns surfaces, the validator owns shape. No guard is weakened: the size
floor is replaced by a shape check, which is strictly more specific than a byte count.
The fingerprint. A background handler failure rendered one generic sentence for every cause, and three
live sessions were spent guessing which throw it was. It now appends the error name and the first
non-extension stack symbol. Redaction is the point of the charset filter: only name-shaped characters
survive, so no message, path, URL or portal value can reach the panel through it.
A reduction pass, in its own commit. The diagnostics module's comment claimed emitters and the
durable allowlist read one list. They did not — emitters wrote string literals and only the
allowlist imported it, so the coupling described in the comment existed nowhere. Emitters now
declare they return one of the listed signals, which makes an unregistered literal a compile
error rather than a runtime rejection of the whole durable array. Mutation-checked: emitting
json-parse-explodedfails the build.The same pass found five structures across three modules holding the two portal refusals — a signal
set, a reason set, a map between them, and two allowlist entries — with the
artifact-prefix thatrelates them stated nowhere. One list and one derivation now. Mutation-checked: dropping a member
from the list fails a consumer test, so the derivation is real rather than decorative.
Closes no review threads; opened fresh.
Scope
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 unchanged. The size floor removed from artifact validation is replaced by a shape check, which is strictly more specific than a byte count, so nothing is weakened. The failure fingerprint is the one new value that reaches a user-visible surface: its charset filter admits only name-shaped characters, and
tests/background/background-failure-fingerprint.test.tsasserts a GSTIN, its digits and a URL are all absent from the output.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
Screenshots
Use synthetic data only.