Prepare approved reporting repair and monthly review inputs

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e738-9e15-7600-87e6-90dec3a7beef
This commit is contained in:
tegwick 2026-09-28 11:22:19 +02:00
parent 9baf6f1829
commit a18d83f74a
16 changed files with 663 additions and 1 deletions

View file

@ -102,7 +102,8 @@ qualified reference use to evidence-bearing consumer receipts and bounded autono
improvement. It owns discovery, instrumentation and execution integration; monthly
human review owns operating-policy decisions. The capability entry is prepared;
automatic collection and three activity-core reporting schedules passed scheduled
smoke checks; the first natural daily receipt remains unverified.
smoke checks; the first natural daily run failed after a worker image change removed
the domain resolver. A tested repair is staged pending release authorization.
Hosted consumer integration and admitted pattern-editing execution remain blocked;
there are no enrolled consumers yet.
This operational loop can improve draft guidance without claiming M1/M2/M3 or

View file

@ -1,5 +1,10 @@
# Activity-core receipt loop
Current diagnosis (2026-09-28): the first natural daily run fired but failed because
the replacement worker image lacks the domain resolver. A tested repair image is
published and awaits the scoped attended-release exception; prior smoke success
is historical. See [repair evidence](evidence/2026-09-28-reporting-repair.json).
FEP-WP-0008 owns this integration. The initial delivery is deterministic collection
and reporting. Automatic investigation and publication are a separate, outstanding
execution dependency; a weekly report is not evidence of an improvement cycle.
@ -134,3 +139,34 @@ September 27 14:07Z smoke receipt. See [recheck](evidence/2026-09-28-loop-rechec
Enabled schedules and prior smoke success do not prove this recurring execution.
WP-0008 T03 retains cadence/sink diagnosis; no outage cause or live fix is claimed.
The roster remains empty and mutation execution remains unadmitted.
## Diagnosed failure and prepared repair — 2026-09-28
Temporal fired the daily definition at 00:00Z. Worker run
`01a0e54f-c690-7caa-bae6-81cd5ed32416` failed with required context source
`frontend-patterns` not registered. Source `428f2d7` changed the worker from the
frontend overlay to the grant-aware API image; the running image has neither the
resolver module nor its registration. ArgoCD and pod readiness were healthy, so
those probes did not establish domain functionality.
[Diagnosis](evidence/2026-09-28-reporting-diagnosis.json),
[schedule readback](evidence/2026-09-28-reporting-schedules.json), and
[repair contract](../integrations/activity-core/README.md) pin the evidence.
The prepared overlay keeps the current grant-aware base and changes only the
domain resolver and its registration. Hash comparison preserves all other Python
source and the grant identity. The candidate also adds monthly owner-snapshot
health, decisions and measured research effort with unknown counts; it never grants
execution authority. Missing review inputs degrade the report visibly.
58 focused tests and 17 GitOps tests pass. Server dry-run passes for the same nine
resources; the actual resource diff is only the worker image. The published digest
is `afd8a7af73132becba432e7b315d70f88d66676020169d5d8811641304136437`.
The October 1 built-image fixture is 1,699 characters and contains no consumers,
unknown eligible-task denominator and unknown cost observations. This is fixture
proof, not an actual October run. Production promotion remains separately gated.
Hosted discovery is still unregistered (404) and its routed write credential is
unavailable to the current operator session. Public source publication passed.
The [consumer hook](../feedback/ConsumerIntegration.md) is prepared, but no real
consumer was fabricated or enrolled. These obligations remain WP-0008 T01/T02.

View file

@ -0,0 +1,31 @@
{
"checked_at": "2026-09-28T09:21:05.990563+00:00",
"public_index_url": "https://forgejo.coulomb.social/coulomb/frontend-patterns/raw/branch/main/registry/indexes/capabilities.yaml",
"public_index_http_status": 200,
"hosted_registration_http_status": 404,
"credential_route": "reuse-surface-hub-write-token",
"credential_owner": "railiance-platform / OpenBao",
"registration_status": "blocked: routed credential unavailable to current operator session",
"credential_output_retained": false,
"consumer_roster_count": 0,
"candidate_scan": "Local workplan titles for frontend/UI/navigation/dashboard/portal/editor/wizard/cockpit across active/ready/blocked/proposed plans. A title scan is not an exhaustive task-level eligibility review.",
"candidates": [
{
"repo": "hub-core",
"workplan": "HUB-WP-0006",
"status": "blocked",
"reason_not_enrolled": "No active consumer decision/outcome inspected or authorized by this session."
},
{
"repo": "rapp-openbao",
"workplan": "RAPP-OPENBAO-WP-0002",
"status": "blocked",
"reason_not_enrolled": "Operator access policy, not a qualified frontend architecture consumption task."
}
],
"finished_examples_not_reopened": [
"vergabe-teilnahme VT-WP-0003/0004",
"state-hub STATE-WP-0048"
],
"consumer_instruction_ref": "feedback/ConsumerIntegration.md"
}

View file

@ -0,0 +1,73 @@
{
"basis": "built-image fixture; future October 1 clock; no production execution",
"bytes": 1699,
"report": {
"repo": "frontend-patterns",
"mode": "monthly",
"generated_at": "2026-10-01T07:00:00+00:00",
"status": "no_consumers",
"execution_ready": false,
"model_calls": 0,
"eligible_tasks": null,
"instrumented_repositories": 0,
"source_revisions": [
"frontend-patterns@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
],
"receipt_events": 0,
"duplicates": 0,
"real_uses": 0,
"synthetic_uses": 0,
"outcomes": {},
"decisions": {},
"signals": [],
"errors": {},
"limits": [
"Producer outcomes are not independently verified.",
"No admitted budget-enforced repository executor; automatic edits disabled.",
"Missing consumer instrumentation means coverage is unknown."
],
"workplan": "FEP-WP-0008",
"executor_dependency": "GLAS-WP-0012 / HFACT-WP-0001",
"window": {
"start": "2026-09-01T00:00:00+02:00",
"end_exclusive": "2026-10-01T00:00:00+02:00"
},
"review": {
"basis": "owner snapshot; not live attestation",
"as_of": "2026-09-28T09:15:00.370856+00:00",
"stale": false,
"health": {
"schedule": "daily fired; collection failed",
"collection": "deployed resolver missing",
"verification": "no consumer outcomes verified",
"publication": "0.1 pinned; repair not deployed",
"rollback": "automatic proof pending",
"executor": "not admitted"
},
"evidence_ref": "docs/evidence/2026-09-28-reporting-diagnosis.json",
"decisions": [],
"default": "Retain current policy/budgets; no new authority or maturity claim.",
"research_cycles": 18,
"measured_effort": {
"research_minutes": {
"known": 43.011,
"unknown_cycles": 11
},
"execution_minutes": {
"known": 3.222,
"unknown_cycles": 11
},
"reported_tokens": {
"known": 0,
"unknown_cycles": 18
},
"cost_usd": {
"known": 0,
"unknown_cycles": 18
}
}
},
"unselected_signals": 0,
"summary": "Frontend patterns monthly: no_consumers; 0 real uses, 0 unverified outcome signals. Automatic edits disabled."
}
}

View file

@ -0,0 +1,22 @@
{
"checked_at": "2026-09-28T09:15:00.370856+00:00",
"workplan": "FEP-WP-0008",
"deployed_source_revision": "428f2d71b0f5ade11457e16d7b6341f571f6735f",
"worker_image": "forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd",
"pod_created_at": "2026-09-27T19:58:36Z",
"worker_ready": true,
"argo_health": "Healthy",
"daily_schedule_id": "activity-schedule-99f02c4c-161e-515d-926d-9e5d11d8411e",
"failed_workflow_id": "activity-99f02c4c-161e-515d-926d-9e5d11d8411e:${firstScheduledTime}-2026-09-28T00:00:00Z",
"failed_workflow_run_id": "01a0e54f-c690-7caa-bae6-81cd5ed32416",
"error": [
"temporalio.exceptions.ApplicationError: Required context source type 'frontend-patterns' is not registered"
],
"worker_module_inspection": {
"frontend_patterns_module_exists": false,
"package_init_imports_frontend_patterns": false
},
"diagnosis": "Source 428f2d7 changed worker from frontend overlay 77244c3 to grant-aware image 713bddad; resolver absent. Schedule fired, required-context failure stopped collection. Healthy pod/Argo status did not cover domain functionality.",
"repair": "Overlay resolver onto current grant-aware image; do not roll back to the older image that lacks grants.",
"production_mutation": false
}

View file

@ -0,0 +1,25 @@
{
"status": "approved_candidate_not_yet_deployed",
"base_image": "forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd",
"candidate_image": "forgejo.coulomb.social/coulomb/activity-core@sha256:afd8a7af73132becba432e7b315d70f88d66676020169d5d8811641304136437",
"upstream_source_revision": "428f2d71b0f5ade11457e16d7b6341f571f6735f",
"tests_passed": 58,
"changed_python_files": [
"context_resolvers/__init__.py",
"context_resolvers/frontend_patterns.py"
],
"all_other_python_source_hashes_unchanged": true,
"grant_identity_preserved": true,
"registry_added": [
"frontend-patterns"
],
"monthly_fixture_ref": "docs/evidence/2026-09-28-monthly-packet-fixture.json",
"production_mutation": false,
"deployment_gate": "Existing 24-hour healthy observation invalidated by required-context failure; attended exact repair exception or admitted owner release lane required.",
"gitops_tests_passed": 17,
"server_dry_run": "passed; nine existing managed resources",
"registry_digest_readback": true,
"worker_image_patch": "integrations/activity-core/worker-image.patch",
"rollback_revision": "428f2d71b0f5ade11457e16d7b6341f571f6735f",
"authorization_decision": "abdea390-1039-4da1-b129-33aad00b4396"
}

View file

@ -0,0 +1,134 @@
[
{
"id": "99f02c4c-161e-515d-926d-9e5d11d8411e",
"name": "Frontend Patterns Daily Review",
"enabled": true,
"trigger_type": "cron",
"schedule_id": "activity-schedule-99f02c4c-161e-515d-926d-9e5d11d8411e",
"definition_source": "database",
"sources": [
"database",
"temporal"
],
"trigger": {
"cron_expression": "0 2 * * *",
"trigger_type": "cron",
"misfire_policy": "catchup_latest",
"jitter_seconds": 0,
"timezone": "Europe/Berlin"
},
"cron_expression": "0 2 * * *",
"at": null,
"timezone": "Europe/Berlin",
"misfire_policy": "catchup_latest",
"catchup_window_seconds": null,
"jitter_seconds": 0,
"temporal": {
"status": "active",
"schedule_id": "activity-schedule-99f02c4c-161e-515d-926d-9e5d11d8411e",
"paused": false,
"last_fired_at": "2026-09-28T00:00:00+00:00",
"missed_catchup_window": 0
},
"drift_hints": [],
"version": 1,
"created_at": "2026-09-27T11:23:29.549570+00:00",
"updated_at": "2026-09-27T11:23:29.549570+00:00",
"side_effect": false,
"trigger_config_public": {
"cron_expression": "0 2 * * *",
"trigger_type": "cron",
"misfire_policy": "catchup_latest",
"jitter_seconds": 0,
"timezone": "Europe/Berlin"
}
},
{
"id": "92e514a6-aeb8-5e22-9292-c62dd26dd757",
"name": "Frontend Patterns Monthly Review",
"enabled": true,
"trigger_type": "cron",
"schedule_id": "activity-schedule-92e514a6-aeb8-5e22-9292-c62dd26dd757",
"definition_source": "database",
"sources": [
"database",
"temporal"
],
"trigger": {
"cron_expression": "0 9 1 * *",
"trigger_type": "cron",
"misfire_policy": "catchup_latest",
"jitter_seconds": 0,
"timezone": "Europe/Berlin"
},
"cron_expression": "0 9 1 * *",
"at": null,
"timezone": "Europe/Berlin",
"misfire_policy": "catchup_latest",
"catchup_window_seconds": null,
"jitter_seconds": 0,
"temporal": {
"status": "active",
"schedule_id": "activity-schedule-92e514a6-aeb8-5e22-9292-c62dd26dd757",
"paused": false,
"last_fired_at": null,
"missed_catchup_window": 0
},
"drift_hints": [],
"version": 1,
"created_at": "2026-09-27T11:23:29.549570+00:00",
"updated_at": "2026-09-27T11:23:29.549570+00:00",
"side_effect": false,
"trigger_config_public": {
"cron_expression": "0 9 1 * *",
"trigger_type": "cron",
"misfire_policy": "catchup_latest",
"jitter_seconds": 0,
"timezone": "Europe/Berlin"
}
},
{
"id": "562005f8-ef43-5a9d-83e2-f09e00e62b81",
"name": "Frontend Patterns Weekly Review",
"enabled": true,
"trigger_type": "cron",
"schedule_id": "activity-schedule-562005f8-ef43-5a9d-83e2-f09e00e62b81",
"definition_source": "database",
"sources": [
"database",
"temporal"
],
"trigger": {
"cron_expression": "0 3 * * 2",
"trigger_type": "cron",
"misfire_policy": "catchup_latest",
"jitter_seconds": 0,
"timezone": "Europe/Berlin"
},
"cron_expression": "0 3 * * 2",
"at": null,
"timezone": "Europe/Berlin",
"misfire_policy": "catchup_latest",
"catchup_window_seconds": null,
"jitter_seconds": 0,
"temporal": {
"status": "active",
"schedule_id": "activity-schedule-562005f8-ef43-5a9d-83e2-f09e00e62b81",
"paused": false,
"last_fired_at": null,
"missed_catchup_window": 0
},
"drift_hints": [],
"version": 1,
"created_at": "2026-09-27T11:23:29.549570+00:00",
"updated_at": "2026-09-27T11:23:29.549570+00:00",
"side_effect": false,
"trigger_config_public": {
"cron_expression": "0 3 * * 2",
"trigger_type": "cron",
"misfire_policy": "catchup_latest",
"jitter_seconds": 0,
"timezone": "Europe/Berlin"
}
}
]

View file

@ -0,0 +1,43 @@
# First consumer integration
FEP-WP-0008 T01/T02 owns this bounded handoff; no consumer is enrolled by this file.
Use the common instruction owner for the selected repository. Do not install a fleet
mandate, reopen a finished task, or invent product work to manufacture adoption.
## Eligibility
A real, open frontend task must need a decision about shared edits, offline recovery,
navigation/rendering, interaction or feature boundaries. The consumer keeps its own
implementation authority. A deployment repair or documentation-only inspection of
this pattern repository is not an external frontend use. Unsupported contexts should
produce an explicit no-match decision, not a forced pattern selection.
## Short planning and closeout instruction
> For eligible frontend architecture work, query
> `capability.infotech.frontend-pattern-language` through hosted reuse-surface.
> Read START.md and the full applicable contracts in the pinned reference release.
> Record its version, packaging revision and manifest digest with selected/rejected
> CAND IDs, task constraints, alternatives and unmet conditions in the task's decision
> note. At closeout, emit an immutable PatternUseReceipt event and index it with its
> SHA-256; unknown outcome is valid. At the first linked test/review/incident, append
> an outcome event with the preceding event digest. Never edit the earlier receipt,
> invent helpfulness, or treat model judgment as observed user benefit.
The [receipt template](../templates/PatternUseReceipt.yaml) and
[index/enrollment contract](README.md) define exact fields. Pin the packaging
revision in [releases.json](../reference/releases.json), not the latest research
HEAD. Read [unsupported contexts](../reference/0.1/README.md) before selecting.
## Acceptance
Before adding an actual consumer to `sources.json`, verify its published receipt
index and immutable event hashes at a concrete revision. Check the source through
activity-core's existing validator/collector. Keep a decision-only unknown outcome
unknown until a linked outcome arrives. Fixture positive/negative paths test the
collector; they do not satisfy real-use acceptance. Enrollment is limited to the
existing allowlist and collection bounds in the runbook.
Hosted registration currently needs the routed OpenBao write credential. Public
index publication is verified, but lookup/registration and a real consumer receipt
must be evidenced separately. Do not infer discovery success from this instruction.

View file

@ -0,0 +1,16 @@
{
"schema_version": 1,
"as_of": "2026-09-28T09:15:00.370856+00:00",
"health": {
"schedule": "daily fired; collection failed",
"collection": "deployed resolver missing",
"verification": "no consumer outcomes verified",
"publication": "0.1 pinned; repair not deployed",
"rollback": "automatic proof pending",
"executor": "not admitted"
},
"evidence_ref": "docs/evidence/2026-09-28-reporting-diagnosis.json",
"decisions": [],
"default": "Retain current policy and budgets; no maturity promotion or execution grant.",
"note": "Owner-maintained snapshot, not live health attestation. Refresh after repair; missing evidence stays unknown."
}

View file

@ -0,0 +1,6 @@
# Preserve the deployed grant-aware runtime; restore only the domain resolver.
FROM forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd
COPY src/activity_core/context_resolvers/frontend_patterns.py /app/src/activity_core/context_resolvers/frontend_patterns.py
RUN printf '\nfrom activity_core.context_resolvers import frontend_patterns # noqa: F401\n' >> /app/src/activity_core/context_resolvers/__init__.py
# Image construction must prove both features coexist, without network or secrets.
RUN python -c "import activity_core.context_resolvers; from activity_core.context_resolvers.base import CONTEXT_RESOLVER_REGISTRY; from activity_core.repository_grant import RepositoryGrant; assert 'frontend-patterns' in CONTEXT_RESOLVER_REGISTRY; assert RepositoryGrant.model_validate({'version':'1','allowed_paths':['docs/'],'commit_count':{'min':1,'max':1},'publish':False}).payload()['publish'] is False"

View file

@ -0,0 +1,54 @@
# Bounded reporting repair for Activity Core
Owner task: FEP-WP-0008 T03, alongside existing ACTIVITY-WP-0041. No new workplan.
The September 27 grant-aware image promotion removed the frontend resolver. Keep
that grant-aware base. This overlay changes only the resolver module and its package
registration; it does not roll back grants, change schedules, or admit a mutation
executor. [Diagnosis](../../docs/evidence/2026-09-28-reporting-diagnosis.json).
`source.json` pins the upstream source revision and resolver hashes. Reproduce with
an isolated checkout of that exact activity-core revision:
```sh
git apply /home/worsch/frontend-patterns/integrations/activity-core/monthly-review.patch
cp /home/worsch/frontend-patterns/integrations/activity-core/Dockerfile Dockerfile.reporting-repair
cp /home/worsch/frontend-patterns/integrations/activity-core/test_frontend_monthly_review.py tests/
PYTHONDONTWRITEBYTECODE=1 .venv/bin/python -m pytest -q -p no:cacheprovider \
tests/test_frontend_patterns.py tests/test_frontend_monthly_review.py \
tests/test_repository_grant.py tests/test_resolve_context_binding.py
docker build -f Dockerfile.reporting-repair -t activity-core:fep-reporting-repair-20260928 .
```
The isolated checkout needs the owner's existing locked development environment.
The Docker build itself needs no new dependency installation: it extends the pinned
runtime and proves resolver registration plus typed grant support during construction.
The review compares all Python source hashes against the base, not only image labels.
The monthly extension reads this repository's `feedback/monthly-review-input.json`,
its cited evidence and learning ledger at the same resolved Git revision. It reports
six health dimensions as an **owner snapshot**, dated and stale after seven days;
these fields cannot grant execution authority. Measured research/execution/token/cost
sums include unknown-cycle counts and only the reporting month. Costs are not inferred
from tokens. At most three bounded decision proposals carry no-response defaults.
Missing input/evidence or invalid effort yields a degraded packet while retaining
receipt totals. The existing 3,900-character digest bound still applies. Daily and
weekly collection remain unchanged. It is not an independent live health observer.
The [October fixture](../../docs/evidence/2026-09-28-monthly-packet-fixture.json)
uses the built image with network disabled and a future clock. It is not an October
production run or completed monthly review. The first actual packet is due October 1.
Deploy only this worker's exact reviewed digest through the existing GitOps source
and ArgoCD path; preserve the API and event-router images and all non-image fields.
The current deployment is `428f2d7`, grant-aware base `713bddad…`; use that exact
revision as the rollback target, acknowledging that rollback restores broken domain
reporting. A rollback must preserve repository grants. Verify resolver and grant
hashes, all three definitions, a report-only scheduled smoke and monthly sink after
rollout. Do not retry the failed historical run as though it had succeeded naturally.
The owner's [release runbook](../../../activity-core/docs/gitops-release.md) requires
24 healthy hours and authenticated release authority. The domain failure invalidates
continuous-health claims; no admitted routine identity exists. An exact attended repair
exception is required before production promotion. Staging this artifact is not that
exception. No access/budget/policy expansion is part of the repair.

View file

@ -0,0 +1,77 @@
--- a/src/activity_core/context_resolvers/frontend_patterns.py
+++ b/src/activity_core/context_resolvers/frontend_patterns.py
@@ -10,6 +10,7 @@
from datetime import datetime, timezone
import hashlib
import json
+import math
from pathlib import PurePosixPath
import re
import time
@@ -149,6 +150,44 @@
return latest
+def monthly_review(root_sha: str, now: datetime, start: datetime, end: datetime) -> dict:
+ """Bounded, source-pinned owner snapshot and measured research totals.
+
+ This is review input, never authority or a live health attestation.
+ Missing/invalid input degrades the monthly packet while preserving receipts.
+ """
+ data = json.loads(raw("frontend-patterns", root_sha, "feedback/monthly-review-input.json"))
+ require(data["schema_version"] == 1, "invalid_monthly_input")
+ stamp = datetime.fromisoformat(data["as_of"].replace("Z", "+00:00"))
+ require(stamp.tzinfo is not None and stamp <= now, "invalid_monthly_date")
+ health = data["health"]
+ keys = {"schedule", "collection", "verification", "publication", "rollback", "executor"}
+ require(isinstance(health, dict) and set(health) == keys, "invalid_monthly_health")
+ require(all(isinstance(v, str) and 0 < len(v) <= 80 for v in health.values()), "invalid_monthly_health")
+ require(path_ok(data["evidence_ref"]), "invalid_monthly_evidence")
+ # The cited file must exist at this same source revision.
+ raw("frontend-patterns", root_sha, data["evidence_ref"])
+ decisions = data["decisions"]
+ require(isinstance(decisions, list) and len(decisions) <= 3, "invalid_monthly_decisions")
+ for decision in decisions:
+ require(isinstance(decision, dict) and set(decision) == {"question", "recommendation", "default"}, "invalid_monthly_decision")
+ require(all(isinstance(v, str) and 0 < len(v) <= 100 for v in decision.values()), "invalid_monthly_decision")
+ ledger = json.loads(raw("frontend-patterns", root_sha, "research/evolution/ledger.json"))
+ events = ledger["events"]
+ require(isinstance(events, list) and len(events) <= 1000, "invalid_learning_ledger")
+ selected = [e for e in events if start.date().isoformat() <= e["date"] < end.date().isoformat()]
+ totals = {}
+ for field in ("research_minutes", "execution_minutes", "reported_tokens", "cost_usd"):
+ values = [e["effort"][field] for e in selected]
+ require(all(v is None or (type(v) in (int, float) and math.isfinite(v) and v >= 0) for v in values), "invalid_effort")
+ totals[field] = {"known": round(sum(v for v in values if v is not None), 3), "unknown_cycles": sum(v is None for v in values)}
+ return {"basis": "owner snapshot; not live attestation", "as_of": data["as_of"],
+ "stale": (now - stamp).total_seconds() > 7 * 86400,
+ "health": health, "evidence_ref": data["evidence_ref"], "decisions": decisions,
+ "default": "Retain current policy/budgets; no new authority or maturity claim.",
+ "research_cycles": len(selected), "measured_effort": totals}
+
+
def collect(mode: str = "daily", now: datetime | None = None) -> dict:
require(mode in {"daily", "weekly", "monthly"}, "invalid_mode")
now = now or datetime.now(timezone.utc)
@@ -165,6 +204,7 @@
"workplan": "FEP-WP-0008", "executor_dependency": "GLAS-WP-0012 / HFACT-WP-0001",
}
config = {"sources": []}
+ root_sha = None
rows = []
events_seen = set()
total = 0
@@ -213,6 +253,13 @@
before = first - timedelta(days=1)
start = before.replace(day=1)
report["window"] = {"start": start.isoformat(), "end_exclusive": first.isoformat()}
+ try:
+ require(root_sha is not None, "missing_root_revision")
+ report["review"] = monthly_review(root_sha, now, start, first)
+ except (ValueError, KeyError, TypeError, AttributeError, OverflowError, httpx.HTTPError):
+ report["review"] = {"status": "unavailable", "health": "unknown", "decisions": [],
+ "default": "Retain current policy/budgets; no new authority or maturity claim."}
+ report["errors"].append("monthly_review_input_invalid_or_unavailable")
# Select latest event as of the end of the month, not latest today.
eligible_rows = [(e, d) for e, d in rows if datetime.fromisoformat(e["recorded_at"].replace("Z", "+00:00")) < first]
latest = reduce_events(eligible_rows, report["errors"])

View file

@ -0,0 +1,7 @@
{
"repository": "coulomb/activity-core",
"revision": "428f2d71b0f5ade11457e16d7b6341f571f6735f",
"resolver_sha256": "598ada41f2835ba08ba60ae7ca06c38acebaadc7c33b46d245a547107b2975e3",
"patched_resolver_sha256": "33aae2f3f0a17dfa90580c611de474064ca52b0aebf73939a9476a8560f46757",
"base_image": "forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd"
}

View file

@ -0,0 +1,87 @@
import copy
import json
from datetime import datetime, timezone
from pathlib import Path
import pytest
from activity_core.context_resolvers import frontend_patterns as f
NOW = datetime(2026, 10, 1, 7, tzinfo=timezone.utc)
INPUT = {'schema_version': 1, 'as_of': '2026-09-28T09:00:00Z',
'health': {k: 'unverified' for k in ('schedule','collection','verification','publication','rollback','executor')},
'evidence_ref': 'docs/evidence/report.json', 'decisions': []}
EVENT = {'date': '2026-09-28', 'effort': {'research_minutes': 4, 'execution_minutes': 1, 'reported_tokens': None, 'cost_usd': None}}
def setup(monkeypatch, data=None, events=None, unavailable=False):
data = copy.deepcopy(INPUT if data is None else data)
events = [EVENT] if events is None else events
def raw(repo, sha, path):
assert repo == 'frontend-patterns' and sha == 'a'*40
if path == 'feedback/sources.json': return b'{"schema_version":1,"sources":[]}'
if path == 'feedback/monthly-review-input.json':
if unavailable: raise ValueError('unavailable')
return json.dumps(data).encode()
if path == 'research/evolution/ledger.json': return json.dumps({'events': events}).encode()
if path == 'docs/evidence/report.json': return b'{}'
raise ValueError('unexpected or missing file')
monkeypatch.setattr(f, 'raw', raw)
monkeypatch.setattr(f, 'revision', lambda *args: 'a'*40)
def test_october_packet_with_no_consumers_retains_health_and_unknown_cost(monkeypatch):
setup(monkeypatch)
r=f.collect('monthly', NOW)
assert r['status']=='no_consumers' and r['model_calls']==0
assert r['window']=={'start':'2026-09-01T00:00:00+02:00','end_exclusive':'2026-10-01T00:00:00+02:00'}
assert r['review']['health']['executor']=='unverified'
assert r['review']['measured_effort']['cost_usd']=={'known':0,'unknown_cycles':1}
assert r['review']['measured_effort']['research_minutes']=={'known':4,'unknown_cycles':0}
assert r['execution_ready'] is False
assert len(json.dumps(r,sort_keys=True,separators=(',',':'))) <= 3900
def test_incomplete_input_degrades_without_losing_receipt_summary(monkeypatch):
setup(monkeypatch, unavailable=True)
r=f.collect('monthly', NOW)
assert r['status']=='degraded' and r['real_uses']==0
assert r['review']['health']=='unknown' and r['review']['decisions']==[]
@pytest.mark.parametrize('change', [
{'as_of':'2026-10-02T00:00:00Z'}, {'as_of':'2026-09-28T00:00:00'},
{'evidence_ref':'../secret'}, {'decisions':[{}]*4},
{'health':{'executor':'ready'}}, {'decisions':[{'question':'x','recommendation':'y'}]},
{'evidence_ref':'docs/evidence/missing.json'},
])
def test_invalid_review_input_never_claims_health(monkeypatch, change):
data=copy.deepcopy(INPUT); data.update(change); setup(monkeypatch,data)
r=f.collect('monthly', NOW)
assert r['status']=='degraded' and r['review']['health']=='unknown'
def test_month_filter_and_missing_effort(monkeypatch):
old=copy.deepcopy(EVENT); old['date']='2026-08-31'
future=copy.deepcopy(EVENT); future['date']='2026-10-01'
unknown=copy.deepcopy(EVENT); unknown['effort']['research_minutes']=None
setup(monkeypatch, events=[old,future,EVENT,unknown])
r=f.collect('monthly', NOW)['review']
assert r['research_cycles']==2
assert r['measured_effort']['research_minutes']=={'known':4,'unknown_cycles':1}
def test_stale_owner_snapshot_is_not_live_health(monkeypatch):
data=copy.deepcopy(INPUT); data['as_of']='2026-09-01T00:00:00Z'; setup(monkeypatch,data)
r=f.collect('monthly',NOW)['review']
assert r['stale'] is True and 'not live attestation' in r['basis']
@pytest.mark.parametrize('value', [-1, float('nan'), True])
def test_invalid_effort_does_not_invent_totals(monkeypatch, value):
event=copy.deepcopy(EVENT); event['effort']['cost_usd']=value
setup(monkeypatch, events=[event])
assert f.collect('monthly', NOW)['status']=='degraded'
def test_daily_does_not_require_monthly_packet(monkeypatch):
setup(monkeypatch, unavailable=True)
assert f.collect('daily', NOW)['status']=='no_consumers'

View file

@ -0,0 +1,22 @@
--- a/k8s/railiance/20-runtime.yaml
+++ b/k8s/railiance/20-runtime.yaml
@@ -2200,7 +2200,7 @@
name: actcore-runtime-config
- secretRef:
name: actcore-runtime-secret
- image: forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd
+ image: forgejo.coulomb.social/coulomb/activity-core@sha256:afd8a7af73132becba432e7b315d70f88d66676020169d5d8811641304136437
imagePullPolicy: IfNotPresent
name: worker
ports:
--- a/k8s/gitops/runtime.yaml
+++ b/k8s/gitops/runtime.yaml
@@ -1653,7 +1653,7 @@
name: actcore-runtime-config
- secretRef:
name: actcore-runtime-secret
- image: forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd
+ image: forgejo.coulomb.social/coulomb/activity-core@sha256:afd8a7af73132becba432e7b315d70f88d66676020169d5d8811641304136437
imagePullPolicy: IfNotPresent
name: worker
ports:

View file

@ -216,3 +216,31 @@ evidence, not a diagnosed scheduler outage. T03 retains cadence/sink verificatio
with activity-core; no schedule was changed and no new task or workplan opened.
[Recheck evidence](../docs/evidence/2026-09-28-loop-recheck.json). October 1's
monthly packet remains due even with no consumers or executor.
## Reporting failure diagnosed and candidate prepared — 2026-09-28
T03: the missing receipt is a real required-context failure, not a missed schedule.
The grant-aware worker promotion at activity-core `428f2d7` removed the frontend
resolver. Prepared and published a scoped overlay preserving all other Python
source and repository-grant identity. It restores registration and adds bounded
monthly owner-snapshot health/decisions plus measured effort/unknown counts.
58 focused tests, 17 GitOps tests, server dry-run and registry readback pass.
[Evidence and exact digest](../docs/evidence/2026-09-28-reporting-repair.json).
The existing release runbook's 24-hour healthy interval is invalidated by the
failure; no routine release identity exists. Exact attended repair approval is
pending. Candidate publication and a future-clock October fixture are not production
repair or actual monthly completion. All three schedules remain enabled and unchanged.
T01/T02: raw capability publication passes, hosted registration returns 404, and
the routed OpenBao registration credential is unavailable to the operator session.
Prepared a short [consumer instruction](../feedback/ConsumerIntegration.md); scanned
local relevant workplan titles but found no ready/active external task to enroll.
Blocked candidates and finished examples are not invented adoption evidence.
[Readiness record](../docs/evidence/2026-09-28-consumer-readiness.json).
Workplan remains blocked; no new task/workplan, consumer enrollment, secret disclosure
or pattern-editing authority was introduced.
The user subsequently approved the exact attended worker repair; State Hub decision
`abdea390-1039-4da1-b129-33aad00b4396`. Promotion and post-rollout proof are now authorized;
this is not standing authority or approval to restore the older grant-unaware image.