Skip to content

refactor(gst): make a target status answer its own questions - #356

Closed
lamemustafa wants to merge 3 commits into
tapish-codex/gstr2b-refusal-period-bindingfrom
tapish-codex/target-status-behaviour
Closed

refactor(gst): make a target status answer its own questions#356
lamemustafa wants to merge 3 commits into
tapish-codex/gstr2b-refusal-period-bindingfrom
tapish-codex/target-status-behaviour

Conversation

@lamemustafa

Copy link
Copy Markdown
Owner

Summary

Makes a full-fiscal-year target status answer its own questions, and fixes the seven
sites that were asking those questions by naming individual members of the union.

Fifth in the stack, on top of #355. Runtime behaviour changes only where a declined
period (not-generated) was previously mishandled.

Root Cause / Decision Record

What was ambiguous. What a target status means was asked as literal comparisons
across twenty-two modules. Nothing connected them, so each was an independent place to
forget. When not-generated joined the union, five sites went on spelling the question
status === "not-filed" and silently answered "no" for every period the portal declined
to draft; two more asked the complement as hand-written arrays that had drifted apart.

Why this is the smallest safe fix. The alternative is fixing each site as it is
reported, which is what produced four consecutive review rounds on this stack. A Record
over the union makes the class unrepresentable: adding a member does not compile until
every question has been answered for it. The Set it replaces sat directly beneath a
comment explaining that a Set over a union is not exhaustiveness-checked -- and had
exactly the defect that comment describes, which is the argument for a structure rather
than another warning.

What it closes. Structurally resolves four open findings on #354
(r3985765507 restaging, r3985765513 discarded-run evidence, r3985765519 no-ZIP
signal, r3985765525's validation half) plus two latent defects nothing had reported:
the diverging actionable/clearable lists, and a stored not-generated record accepted
with no evidence behind it. Thread numbers are indicative -- see the table below once
review runs against this head.

Scope

  • Runtime: filed-returns-contracts.ts (the table); seven call sites in
    filed-returns-full-fiscal-year-{summary,staging,run-state,validation}.ts,
    filed-returns-all-supported-full-fiscal-year-validation.ts,
    filed-returns-current-state.ts, local-data.ts.
  • Tests: tests/connectors/filed-returns-target-status-behaviour.test.ts (invariants),
    tests/background/full-fiscal-year-declined-period-handling.test.ts (behaviour).
  • Docs/governance: none.
  • Explicitly out of scope: the ledger-status union (complete/partial/...), which has
    its own two hand-maintained copies; TerminalStatus in core/contracts.ts, which
    shares two spellings with this union and is a different vocabulary; and typing
    safeSignals beyond string[], which is the same class at 190 call sites and belongs
    in its own change.

Pack Workflow Preflight

  • pnpm workflow:preflight was run before editing/push, or the skip reason is documented.
  • This PR was opened from a Pack branch, not master.
  • I checked latest master Pack AGENTS guidance or recorded the stale-guidance warning.
  • PR body keeps the required Pack privacy/review/verification checklist visible.

Sanchika Adoption Gate

  • If this PR consumes @sanchika/* packages or copied Sanchika guidance, I
    read sanchika/docs/adoption-pack.md in the coordinated parent worktree.
  • If this PR consumes Sanchika, it links ComplyEaze and Axal completion evidence
    and records the Sanchika commit or copied guidance used.
  • This PR does not import ../sanchika, sanchika/packages/*/src, or parent
    source paths.

Privacy And Data-Flow Impact

  • No new browser permissions.
  • No new host permissions.
  • No new network calls.
  • No analytics, telemetry, ads, or session replay.
  • No credential, OTP, CAPTCHA, cookie, token, GST file, or taxpayer-data capture.
  • Public copy and privacy declarations are updated if behaviour changed.

Sensitive Surface Review

  • Current tab / portal target binding is preserved or intentionally changed.
  • Download completion remains evidence-backed and fail-closed.
  • Ambiguous side-effect delivery cannot be reported as confirmed success.
  • Service-worker durability impact is understood and documented.
  • Real taxpayer data, local paths, raw URLs/referrers, and portal HTML are absent from the diff.

Chrome Web Store Impact

  • This PR does not expand beyond the existing Chrome Web Store V0 listing unless every gate in docs/PUBLICATION_READINESS.md is checked.
  • Full fiscal year remains source-only and excluded from the next packaged Store build until its evidence gates are recorded.
  • Store copy, README status, Privacy QA, and reviewer instructions were reviewed if user-facing behavior changed.
  • CI ZIP creation, provenance, and protected publishing are treated as release evidence, not manual store-submission sign-off.
  • PR title uses Conventional Commits so Release Please can bump Pack after merge.

Verification

  • pnpm install --frozen-lockfile
  • pnpm audit --audit-level high
  • pnpm exec wxt prepare
  • pnpm exec prettier --check .
  • pnpm exec eslint . --max-warnings 0
  • pnpm exec tsc --noEmit
  • pnpm exec vitest run
  • pnpm exec wxt build
  • node scripts/verify-extension-package.mjs .output/chrome-mv3
  • pnpm exec wxt zip
  • node scripts/verify-extension-zip.mjs
  • node scripts/write-release-provenance.mjs
  • node scripts/verify-github-release-assets.mjs --tag <tag> --zip <zip> --checksum <sha256> --provenance <json> when release assets exist
  • node scripts/publish-chrome-web-store.mjs --zip .output/<zip> --provenance .output/pack-release-provenance.v1.json --publisher-id <id> --dry-run true
  • git diff --check
  • pnpm review:gate -- --strict-head-review --wait-head-review-ms 180000 before merge/readiness claim; a missing Codex review blocks readiness:

Artifact Evidence

  • CI run: pending on this head.
  • ZIP artifact: not a release PR.
  • ZIP SHA-256: not a release PR.
  • Clean source/tag or head SHA: dc67c92.

Local gates on dc67c92, quoted verbatim:

prettier=0
eslint=0
tsc=0
 Test Files  181 passed (181)
      Tests  3379 passed (3379)

Base (e881215) was 179 files / 3353 tests, so this adds 2 files and 26 tests and
removes none. Both behaviour cases fail when their site is reverted to the literal it
used to spell; the mutation was run for each separately.

PR Review Follow-Up

  • GitHub Actions completed.
  • Autogenerated Codex/bot review comments inspected after checks completed for the latest head SHA.
  • Inline review threads are resolved, outdated, or answered with evidence.
  • No commits were pushed after the last required human/bot review without re-review.
  • Any follow-up PRs or issues are listed here instead of being left implicit.
Thread/comment Disposition Commit or evidence
(none yet -- first review round)

Note for review. Two behaviour changes are deliberate and worth checking rather than
assuming:

  1. local-data.ts now refuses to clear local data when a target sits at cancelled,
    where it previously allowed it. That is the stricter side of a divergence between two
    hand-written lists -- filed-returns-current-state.ts counted cancelled as
    actionable, so the panel could surface a ledger the clear would delete. Fail-closed
    was chosen for a destructive action; say so if the looser reading was intended.
  2. Restaging now leaves not-generated targets alone. Nothing was staged for them, so
    nothing needs restaging, and resetting them to blocked sent the run back to periods
    the portal had already answered.

Screenshots

None -- no user-visible surface changed.

What a status means was asked as literal comparisons in twenty-two modules.
Nothing connected them, so each was an independent place to forget -- and when
`not-generated` joined the union, five separate sites went on spelling the
question `=== "not-filed"` and silently answered "no" for every period the
portal declined to draft.

`TARGET_STATUS_BEHAVIOUR` is a `Record` over the union, so adding a member does
not compile until every question has been answered for it. That is the whole
difference between this and the `Set` it replaces -- which sat directly beneath
a comment explaining that a `Set` over a union is not exhaustiveness-checked,
and had the defect that comment describes.

Two questions are new because the code was asking them without naming them.
`statedAbsence` is "is there a file to expect here?", which has one answer for
both `not-filed` and `not-generated` even though a reader must keep them apart:
one is a claim about the taxpayer, the other about the portal.
`requiredEvidenceSignal` is the evidence a stored record claiming this status
must carry, which two validators had each spelled out for `not-filed` alone.

`isResolvedFullFiscalYearTargetStatus` and `needsExplicitFullFiscalYearRetry`
are unchanged in behaviour and now read from the table.
…f it

Each asked "is there a file to expect for this period?" and spelled it
`status === "not-filed"`, so each answered "no, keep working" for a period the
portal had already declined to draft:

- evidence retained from a discarded run dropped declined periods entirely;
- a year of declined periods was not recorded as having produced no ZIP;
- restaging reset declined periods to `blocked`, sending the run back to
  periods the portal has answered;
- two ledger validators accepted a stored `not-generated` record carrying no
  evidence that anything had been declined, while rejecting the equivalent
  `not-filed` record.

Two more sites asked the complement -- "does this ledger still hold anything
unresolved?" -- as hand-written arrays, and the two copies had drifted apart:
`filed-returns-current-state.ts` listed seven members and `local-data.ts` six,
omitting `cancelled`. A ledger the panel was still surfacing as the current run
could therefore be cleared from under it by the local-data guard. Both now ask
the question rather than enumerate an answer.

`hasTerminalPositiveTarget` was `resolved || "manually-observed"`, which is what
`holdsAnswer` means, so it says that instead.
…vers

The invariants hold the table together: a stated absence resolves a target and
stages nothing, anything resolved is an answer worth keeping, and every status
lands in exactly one of active, resolved, or needs-a-decision.

Both behaviour cases fail when their site is reverted to the literal it used to
spell.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 12, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-12T07:14:34.136749Z dc67c92 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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

ℹ️ 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 src/background/filed-returns-full-fiscal-year-summary.ts
@lamemustafa

Copy link
Copy Markdown
Owner Author

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.

@lamemustafa
lamemustafa marked this pull request as draft September 12, 2026 11:12
@lamemustafa

Copy link
Copy Markdown
Owner Author

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.

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