state-hub/docs/evidence/2026-10-04-forge-qualifier-receiving.md
tegwick 3791e608ba
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 29s
Verify offline scaffolds and preserve Forge qualifier receiving
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a10391-6355-7b41-b0fa-3e14e874f091
2026-10-04 02:32:37 +02:00

63 lines
3.7 KiB
Markdown

# STATE-WP-0094-T04 — Forge qualifier receiving source validation
The committed source model already supports task decision_id, blocked_on,
wait_until and flavor, and workplan flavor, flavor_promotion_reason and
flavor_promoted_from. Forge receiving omitted them. The correction carries them
through source derivation, projection JSON, dry-run diff, creation of a new
workplan/task, creation of a task on an existing workplan, and updates of existing
rows. It reuses the established closed flavor vocabulary and normalization.
Source authority is explicit: absent or YAML-null qualifiers/flavors clear stored
values; quoted false clears needs_human. Existing identities are retained.
Date-only values remain datetime.date in persistence and ISO dates in JSON.
Bare/quoted timestamps, impossible dates, malformed qualifier YAML, invalid
boolean/text qualifiers and unknown flavor values refuse derivation before
receiving can update or cancel stored gates. The existing ForgeDeriveError API
path reports the refusal. Origin and origin_ref are retained only in source;
no schema or migration was added. Activity Core historical shared identities
and frontmatter task parsing are outside this correction.
## Validation and retained failed trial
Actual source validation command, run alone because the fixture database has a
session-level schema lifecycle:
```sh
PYTHONDONTWRITEBYTECODE=1 .venv/bin/python -m pytest -p no:cacheprovider tests/test_forge_projection.py tests/test_forge_projection_qualifiers.py tests/test_work_record_projection_api.py tests/test_work_record_flavor.py tests/test_wait_kind.py -q
```
Final result: **130 passed in 41.68s**. `git diff --check` passes. Ruff is unavailable
in the repository venv and PATH; no lint result is claimed.
Earlier trial: **127 passed, two failed**. Both failures exposed PyYAML's plain
ValueError for the impossible bare date 2099-02-31. Catching YAML/ValueError as a
whole-derivation refusal fixed the regression. Review before that run also found
datetime accepted through isinstance(date); exact date acceptance and timestamp
regressions corrected it. These are refinements of one trial, not extra successes.
The real API/PostgreSQL regression proves residual creation and exclusion from
open views, promotion metadata, task creation on existing parents, qualifier
updates, source null/absent clearing, unchanged UUIDs, normalized quoted false,
independent repeat noop, and no stored-row changes after invalid source.
Tested SHA256 values:
- api/services/forge_projection.py: d935fc6c9cb34c5d340ac09f02c929c4244a5fb2b2cf44796972083e98c98516
- tests/test_forge_projection_qualifiers.py: a9c83c8b312f61e540d9f131c47c2adacabe219ae89644e480a9354668f27491
## Boundaries and remaining live work
This is local source correctness, not a production receiving receipt. T05 owns
current deployed revision, reviewed image/rollout/rollback preparation, separate
production authorization and primary parity through normal immutable Forge
reconciliation; direct C-41 repairs do not satisfy it. T05 also retains actual
graph edge/freshness coverage. T03 retains supported runner selection, pickup
deduplication and receipts; the execution launch-request consumer is retired.
No deployment, schedule or human decision resolution occurred.
The historical CLI symptom remains distinguished. Today's CLI uses the same
checker and deliberately turns warnings-only exit 2 into shell success. C-16
can skip writes, so successful process exit alone is not field parity. The prior
Forge receiving omitted new fields on creation and ignored them on existing
rows, including source removal; that does not prove it actively erased earlier
correct qualifiers or explain every historical CLI/direct-run discrepancy.