core/docs
Shay 72fac59029
feat(ADR-0161.3): submission-time invariants — duplicate + dependent_on_pending auto-reject (#313)
Adds two pre-gate checks to propose_from_candidate that fire after the
Step 2 capacity check and before the replay gate.  No log entry is
written on either refusal — the append-only invariant holds.

Check order at function entry (ADR-0161 §3):
  1. Capacity (Step 2)          → RefusedAtCapacity
  2. Duplicate                  → RefusedAsDuplicate
  3. Dependent_on_pending       → RefusedAsDependent
  4. Replay gate                → auto-reject on regression

New frozen dataclasses:

  @dataclass(frozen=True, slots=True)
  class RefusedAsDuplicate:
      proposal_id: str
      existing_state: str        # covers all states: pending/accepted/rejected/withdrawn
      reason: str = "duplicate"

  @dataclass(frozen=True, slots=True)
  class RefusedAsDependent:
      candidate_id: str
      dependent_on: tuple[str, ...]       # pending proposal_ids that block
      overlapping_lemmas: tuple[str, ...] # normalised lemmas that triggered
      reason: str = "dependent_on_pending"

Lemma-overlap rule: case-insensitive exact-match on strip().lower().
Conservative — over-reject rather than admit-with-hidden-dependency.
False positives are recoverable (re-emit after blocker is ratified);
false negatives silently couple ratification choices.

CLI surfaces both outcomes in cmd_teaching_propose and
cmd_teaching_propose_from_exemplars (exit code 1).

Step 2 backpressure tests updated: made pre-populated candidates use
unique objects to avoid triggering the new dependency check, and
updated idempotency assertions to reflect the new RefusedAsDuplicate
return for re-submitted content.

Co-references: ADR-0161 §3, Step 1 PR #296, Step 2 PR #311,
ADR-0057, ADR-0151.
2026-05-26 16:46:25 -07:00
..
adr feat(runtime): opt-in unified-ingest path (ADR-0090, audit Findings 6+7) (#95) 2026-05-20 21:00:27 -07:00
architecture
audit fix(phase2): close W-006/W-010/W-013/W-014/W-019 operator decisions (#270) 2026-05-25 11:34:19 -07:00
briefs feat(W-019): learning-arc demo — engine-authored proposal from contemplation (ADR-0152) (#276) 2026-05-25 13:03:10 -07:00
curriculum docs(adr-0087): rhetorical style as selection axis + writing-chain harvester spec (#72) 2026-05-20 16:09:16 -07:00
decisions feat(ADR-0161.3): submission-time invariants — duplicate + dependent_on_pending auto-reject (#313) 2026-05-26 16:46:25 -07:00
evals docs(evals): articulation benchmark preamble — discourse-planner spine 2026-05-19 12:47:38 -07:00
handoff docs(handoff): two Codex briefs — domain-pack closure cleanup + grc/he content phase II (#98) 2026-05-20 23:12:15 -07:00
implementation docs: propose semantic-symbolic binding graph layer (#170) 2026-05-23 09:58:39 -07:00
sessions docs(session): 2026-05-26 corridor closure — first GSM8K lift + workbench operational (#305) 2026-05-26 13:49:08 -07:00
workbench feat(W-028): chat surface + trace drawer (#303) 2026-05-26 13:22:11 -07:00
admissibility-exemplars.md feat(ADR-0163.B.2): four new exemplar corpora — discrete_count_statement, multiplicative_aggregation, currency_amount, plus temporal_aggregation v2 widening (#306) 2026-05-26 14:36:59 -07:00
capability_roadmap.md docs: Phase 5 GSM8K-math substrate completion sweep (ADR-0119 + sub-phases + ADR-0114a 10/10) 2026-05-22 20:39:24 -07:00
ethics_packs.md feat(adr-0034): EthicsCheck — structural surface parallel to SafetyCheck 2026-05-17 20:46:34 -07:00
EVAL_AUDIT_2026-05-20.md chore(evals): contracts + bench json + Lane B viewer + chart + audit + demo schema (#62) 2026-05-20 13:53:13 -07:00
eval_methodology.md feat: ADR-0113 rename expert-demoaudit-passed; reserve expert namespace (ADR-0114 GSM8K roadmap) 2026-05-22 15:36:10 -07:00
formation_pipeline_plan.md docs: teaching-order doctrine + refresh formation/roadmap status 2026-05-17 18:48:44 -07:00
frontier_baselines.md
gaps.md Add chain-first capability ledger and domain seeds (#97) 2026-05-20 21:33:24 -07:00
hitl-backpressure.md feat(ADR-0161.3): submission-time invariants — duplicate + dependent_on_pending auto-reject (#313) 2026-05-26 16:46:25 -07:00
holdout_recipients.txt feat: ADR-0119.1 — seal fabrication_control holdout with age encryption (Obligation #1) 2026-05-22 17:22:46 -07:00
identity_packs.md feat(surface): ADR-0031 — score-decomposition surface (per-axis hedges) 2026-05-17 20:16:22 -07:00
master-plan-post-substrate-audit.md docs(session): 2026-05-26 corridor closure — first GSM8K lift + workbench operational (#305) 2026-05-26 13:49:08 -07:00
pack_inventory_2026-05-21.md docs: pack inventory 2026-05-21 — strengths, weaknesses, leverage gaps (#84) 2026-05-20 19:59:18 -07:00
PROGRESS.md docs(session): 2026-05-26 corridor closure — first GSM8K lift + workbench operational (#305) 2026-05-26 13:49:08 -07:00
recognizer-registry.md feat(ADR-0163.D): wire ratified RecognizerSpecs into math_candidate_graph admissibility surface (#302) 2026-05-26 13:11:47 -07:00
refusal-taxonomy.md feat(ADR-0163.A): refusal taxonomy lane — shape categorization of GSM8K admissibility gaps (#297) 2026-05-26 11:27:11 -07:00
reviewers.yaml fix(quarantine): drain all 60 quarantined tests — QUARANTINE=∅ (#267) 2026-05-25 11:22:12 -07:00
runtime_contracts.md docs: Phase 5 GSM8K-math substrate completion sweep (ADR-0119 + sub-phases + ADR-0114a 10/10) 2026-05-22 20:39:24 -07:00
RUST.md
safety_packs.md feat(safety): ADR-0032 — SafetyCheck structural surface 2026-05-17 20:25:22 -07:00
teaching_order.md feat(identity-packs): ADR-0027 — swappable identity manifold via packs 2026-05-17 19:24:39 -07:00
test-debt-quarantine.md ci: full-pytest gate + QUARANTINE registry (49 known failures, uv) (#263) 2026-05-25 06:21:04 -07:00
truth_seeking_schema.md
Whitepaper.md docs: Phase 5 GSM8K-math substrate completion sweep (ADR-0119 + sub-phases + ADR-0114a 10/10) 2026-05-22 20:39:24 -07:00
Yellowpaper.md docs: Phase 5 GSM8K-math substrate completion sweep (ADR-0119 + sub-phases + ADR-0114a 10/10) 2026-05-22 20:39:24 -07:00