Skip to content

Phase 12C — Ops maturity#14

Merged
proofoftrust21 merged 8 commits intomainfrom
phase-12c-ops
Apr 22, 2026
Merged

Phase 12C — Ops maturity#14
proofoftrust21 merged 8 commits intomainfrom
phase-12c-ops

Conversation

@proofoftrust21
Copy link
Copy Markdown
Owner

@proofoftrust21 proofoftrust21 commented Apr 21, 2026

Summary

Phase 12C — dettes d'ops post cut-over Phase 12B (Postgres live). Cinq
livrables, un blocage checkpoint 3.

# Ticket Statut Commit
C1 CI Postgres service wiring 8946ca3
C2 Observer 401 investigation ✅ SUPERSEDED fbfcaf6
Observer Protocol sunset (S1-S7) c38472f
C3 service_endpoints vide post-migration 116e533
C4.1 TS errors audit (src/tests/**) 116e533
C4.2-3 Execute TS sweep BLOCKED Checkpoint 3
C5 scripts/checkScoringHealth.sh d89f481
C6 Final report c944767

Détail complet : docs/phase-12c/PHASE-12C-OPS-REPORT.md.

Checkpoint 3 attendu

Décision Romain sur scope du sweep TS errors :

  • A — Intégral (25-45h) : porter tous les tests skipped au client
    Postgres, remonter coverage à pré-Phase 12B.
  • B — Partiel recommandé (6-9h) : 8 fichiers à impact fonctionnel
    réel + delete migration-era skip + @ts-nocheck scripts archivés +
    lint CI.
  • C — Statu quo (0h) : laisser exclude: src/tests/**, tracker la
    drift via lint périodique.

Chiffres dans docs/phase-12c/TS-ERRORS-AUDIT.md.

Déploiement

  1. make deploy && docker compose build api crawler && docker compose up -d --force-recreate
  2. Après restart, le registry crawler fire une passe initiale →
    populate service_endpoints (≈94 endpoints depuis 402index).
  3. /api/intent/categories redevient non-vide.
  4. Lancer ./scripts/checkScoringHealth.sh post-deploy puis à T+24h
    pour valider la stabilisation.

Test plan

  • npm run lint green (tsc --noEmit).
  • npm test : 1043 passed / 289 skipped / 0 failed (post sunset).
  • /api/health check 1 vert sur prod pre-deploy (status=ok).
  • curl https://402index.io/.../services reachable (HTTP 200).
  • Post-deploy : ./scripts/checkScoringHealth.sh → GREEN (0 FAIL).
  • Post-deploy : psql -c "SELECT COUNT(*) FROM service_endpoints" > 0.
  • Post-deploy T+24h : logs crawler level>=error < 50 / 24h.
  • Checkpoint 3 décision reçue → C4.2-3 exécuté (ou statu quo documenté).

Risques

  • Registry crawler premier fire : prend ≈ 100×500ms ≈ 50s bloquant-à-500ms-intervals.
    Fire-and-forget donc n'affecte pas la boot du crawler container.
  • Le sunset Observer retire du code runtime live : bien attendre le
    rebuild des images docker (pas juste make deploy).

Adds a postgres:16-alpine service container to the test job with
healthcheck so the Node test harness's globalSetup can connect and
bootstrap the template DB. DATABASE_URL env var matches the default
that src/tests/helpers/testDatabase.ts falls back to.

Fixes the CI failure pattern observed on PR #13:
  Error: connect ECONNREFUSED 127.0.0.1:5432
  at Object.setup (src/tests/helpers/globalSetup.ts:25:22)

Credentials mirror the satrank/satrank/satrank default used locally so
we do not diverge test expectations between dev and CI. GitHub Actions
waits for the service healthcheck to pass before starting the job
steps, so no external wait-for-it script is needed.
Root cause analysis — no fix applied, decision deferred to checkpoint 1.

Three compounding defects produce the continuous 401 flood:
1. Client (observerClient.ts:52-56) sends no Authorization header.
2. Upstream /observer/transactions is now gated (401 anonymous).
3. Prod env OBSERVER_API_URL=api.observer.casa is orphaned — code
   never reads it, host NXDOMAIN.

Impact: zero Observer ingestion (12291 agents all lightning_graph),
~1440 ERROR lines/day polluting crawler logs. Not migration-caused;
predates Phase 12B. Four fix options documented for user decision.
…rename enum to 'attestation', reposition narrative from "AI agents" to "autonomous agents on Bitcoin Lightning"

Product decision 2026-04-22: Observer Protocol is repositioned as a
narrative-trust competitor, not a partner. SatRank fully disengages.

Code
- Delete src/crawler/observerClient.ts, observerCrawler (formerly crawler.ts),
  src/tests/crawler.test.ts, src/tests/dualWrite/idempotence-crawler.test.ts,
  src/tests/verdictObserverSkip.test.ts
- Rename AgentSource enum: 'observer_protocol' → 'attestation' across
  repositories, services, controllers, scripts and tests
- Remove 'observer' from BucketSource enum; dead branch in bayesian pipeline
  (bayesianScoringService, dailyBucketsRepository, streamingPosteriorRepository)
  deleted; CHECK constraint in postgres-schema.sql narrowed to
  ('probe', 'report', 'paid')
- Strip Phase 3 "observer fallback" from backfillTransactionsV31.ts (the
  orphan-source tagger is obsolete now that 'observer' isn't a valid
  transactions.source)
- Update scoringService + config/scoring.ts verified-tx bonus comments
  (Observer-specific → generic attested txns)

Database schema
- agents.source CHECK: ('attestation', '4tress', 'lightning_graph', 'manual')
- *_streaming_posteriors.source and *_daily_buckets.source CHECK narrowed
- transactions.source CHECK: ('probe', 'report', 'paid', 'intent'),
  IS NULL allowed (legacy rows)

Config
- .env.example: remove OBSERVER_BASE_URL, OBSERVER_TIMEOUT_MS,
  CRAWL_INTERVAL_OBSERVER_MS
- src/config.ts: drop the same entries from the zod schema
- DEPLOY.md env reference: drop CRAWL_INTERVAL_OBSERVER_MS lines
- Prod .env.production: remove orphan OBSERVER_API_URL=https://api.observer.casa
  (backup .env.production.bak-observer-sunset kept on the host)

Narrative repositioning (D4)
- "AI agents"/"agents IA" → "autonomous agents"/"agents autonomes",
  default to "autonomous agents on Bitcoin Lightning" when ambiguous
- Touches: src/openapi.ts, src/mcp/server.ts, mcp-server.json,
  sdk/package.json, python-sdk/pyproject.toml, sdk/README.md, README.md,
  package.json, public/index.html, public/methodology.html,
  IMPACT-STATEMENT.md, INTEGRATION.md

Docs
- docs/phase-12c/OBSERVER-SUNSET.md (new): sunset decision record,
  scope, and reactivation condition (explicit written partnership only)
- docs/phase-12c/OBSERVER-401-INVESTIGATION.md: marked SUPERSEDED,
  OBSERVER_API_URL/OBSERVER_BASE_URL mismatch clarified
- docs/phase-12c/OPS-ISSUES.md: new Finding D — Observer sunset RESOLVED

Verification
- npx tsc --noEmit: 0 errors
- npm test: 1043 passed / 289 skipped / 0 failed (119 files)
- Test template DB dropped + re-seeded with updated CHECK constraints

Reactivation policy: no flag, no env toggle, no silent redeploy.
A future reactivation requires an explicit written partnership committed
to docs/partnerships/ and a clean reimplementation.
…rors (C4.1)

- runFullCrawl() never triggered registry crawler; fresh cut-overs left
  service_endpoints empty for 24h until the first setInterval fire. Add
  initial fire-and-forget call in cron boot so /api/intent/categories
  populates immediately on deploy.
- Finding B flipped RESOLVED in OPS-ISSUES.md with full diagnostic
  (prod COUNT=0, 402index reachable, port B3.b not at fault).
- Add TS-ERRORS-AUDIT.md: 257 TS errors in src/tests/** classified
  Trivial/Ciblé/Profond with 3 execution options (A integral, B partial
  RECOMMENDED, C status quo). Awaiting CHECKPOINT 3 user decision.
Manual one-shot sanity check for T+24h post-deploy. Vérifie :
- /api/health status + scoringStale/scoringAgeSec,
- agents count (≥ 1000),
- score_snapshots freshness (< 15min idéal, 1h warn, > 1h fail),
- endpoint_streaming_posteriors freshness (< 1h),
- service_endpoints populé (validation fix Finding B/C3),
- crawler ERROR logs 24h (budget 50).

Sortie colorée (OK/WARN/FAIL) + verdict GREEN/YELLOW/RED avec exit code
0/1/2. Read-only (ssh + docker exec), pas de modification prod.

Baseline pre-deploy : 1 FAIL + 4 WARN (service_endpoints vide attendu
tant que le fix registry n'est pas déployé).
Rapport final couvrant C1 (CI postgres), C2+sunset (Observer), C3
(registry initial fire), C4.1 (TS audit), C5 (health script). C4.2-3
reste bloqué en Checkpoint 3 (décision Romain sur scope TS sweep).

Documente baseline pre-deploy du health script (1 FAIL + 4 WARN
attendus) et état attendu post-deploy (GREEN + au plus 1 WARN).
@proofoftrust21 proofoftrust21 changed the title Phase 12C — Ops maturity (WIP draft) Phase 12C — Ops maturity (draft) Apr 21, 2026
…sts gate

Option B with user-directed adjustments (Checkpoint 3, 2026-04-22):
- B2 archive: 13 SQLite-era test files git-mv'd to src/tests/archive/ with
  @ts-nocheck headers and TODO Phase 12D. Vitest excludes the archive dir so
  runtime discovery stays clean.
- B1 ports (priority order): probeCrawler (core coverage, 5 tests un-skipped
  and now passing), verdict, verdictAdvanced, reportAuth, integration,
  reportBonus, serviceHealth, lndGraph, reportSignal, production. All
  db.prepare().run()/.get() converted to await db.query($1, ...).
- Non-B1 small fixes: voie3-anonymous-report, depositTierService null guard,
  nostr{Deletion,Publisher,Scheduler} async return types, ssrf-probe-poc
  @ts-nocheck (PoC uses SQLite).
- retention.test.ts + phase3EndToEndAcceptance.test.ts: @ts-nocheck + TODO
  Phase 12D (deep SQLite helpers / API drift respectively; still describe.skip
  at runtime).
- B4 separate test config: new tsconfig.tests.json + package.json lint:tests
  script — main tsconfig keeps src/tests/** excluded (production build
  unchanged).
- B5 CI wiring: npm run lint:tests added to .github/workflows/ci.yml.

Gates: npm run lint 0 err, npm run lint:tests 0 err, npm test 1048 passed /
169 skipped / 0 failed (was 1043 pre-sweep — +5 from probeCrawler un-skip).
@proofoftrust21 proofoftrust21 marked this pull request as ready for review April 21, 2026 23:40
@proofoftrust21 proofoftrust21 changed the title Phase 12C — Ops maturity (draft) Phase 12C — Ops maturity Apr 21, 2026
proofoftrust21 added a commit that referenced this pull request Apr 22, 2026
* feat(phase-6.1): SDK 1.0.0 GA (TypeScript + Python), ready to publish

Promote both SDKs from RC to stable 1.0.0 with minor drift fixes.

TypeScript (@satrank/sdk)
- Add "consider_alternative" to AdvisoryBlock.recommendation union (matches
  the four server values)
- Remove dead ApiClient.getAgentVerdict() (never wired to the public surface)
- Rewrite README for the narrow 1.0 surface (SatRank, fulfill, listCategories,
  resolveIntent, wallet drivers, parseIntent) — the previous README still
  documented the deprecated SDK 0.x SatRankClient
- Narrative: "AI agents" -> "autonomous agents on Bitcoin Lightning"
- Version: 1.0.0-rc.1 -> 1.0.0

Python (satrank)
- Add "consider_alternative" to AdvisoryBlock.recommendation Literal
- Narrative update in pyproject.toml description
- Version: 1.0.0rc1 -> 1.0.0

Validation
- 125/125 TS tests pass, tsc build + lint green
- 116/116 Python tests pass, mypy --strict + ruff green
- Live smoke against https://satrank.dev: /api/health 200 (schema v41,
  8186 agents), /api/intent/categories shape OK, invalid category surfaces
  ValidationSatRankError correctly in both SDKs

Phase 12C note
- AgentSource/BucketSource enum sunset (PR #14) is transparent: neither SDK
  references the enums. No code change required here.

Docs
- docs/phase-6.1/SDK-DRIFT-AUDIT.md (S1 deliverable)
- docs/phase-6.1/SDK-INTEGRATION-TEST.md (S4 deliverable)
- docs/phase-6.1/RELEASE-NOTES-DRAFT.md (S5 deliverable, for manual publish)
- docs/phase-6.1/SDK-UPDATE-REPORT.md (S6 deliverable)
- sdk/CHANGELOG.md and python-sdk/CHANGELOG.md (new)

PUBLISH GATE remains closed: artifacts built locally only
(sdk/satrank-sdk-1.0.0.tgz untracked; python-sdk/dist/ gitignored).
No npm publish / twine upload / gh release / git tag has been run.
See RELEASE-NOTES-DRAFT.md for the manual publication checklist.

* chore(sdk-1.0): align SDK licenses to MIT, bump Python classifier to Stable, fix keyword drift

Pre-publish adjustments for SatRank SDK 1.0.0 GA.

License — both SDKs to MIT (client-side permissive, max adoption)
- sdk/package.json: "license": "AGPL-3.0" -> "MIT"
- sdk/README.md: license section -> MIT
- sdk/LICENSE: new MIT file (copyright 2026 Romain Orsoni / SatRank)
- sdk/package.json "files": add "LICENSE" to the npm publish list
- python-sdk/LICENSE: new MIT file (matches existing
  pyproject.toml license = { text = "MIT" })

Python metadata
- classifiers: "Development Status :: 4 - Beta" -> "5 - Production/Stable"
  (coherent with 1.0.0 GA)
- keywords: "ai-agents" -> "autonomous-agents" (narrative consistency
  with the TS SDK and the rest of the Phase 6.1 wording)

Rationale
- MongoDB / Elastic pattern: server core stays AGPL-3.0 (protects the
  SatRank oracle backend); client SDKs are MIT (removes friction for
  agent developers). The economic protection via L402 on paid endpoints
  is orthogonal and unchanged.

Artifacts rebuilt (not committed — matches prior policy)
- sdk/satrank-sdk-1.0.0.tgz: 41.0 kB, 59 files, bundles LICENSE + README
- python-sdk/dist/satrank-1.0.0-py3-none-any.whl + .tar.gz: LICENSE
  auto-included by setuptools in dist-info/licenses/
- Stale python-sdk/dist/satrank-1.0.0rc1.* removed during clean rebuild.

PUBLISH GATE remains closed. No npm publish, no twine upload, no
gh release, no git tag. Ready for manual publish per
docs/phase-6.1/RELEASE-NOTES-DRAFT.md once validated.

* ci: wire postgres 16 service container for npm test (Phase 12C #1)

Adds a postgres:16-alpine service container to the test job with
healthcheck so the Node test harness's globalSetup can connect and
bootstrap the template DB. DATABASE_URL env var matches the default
that src/tests/helpers/testDatabase.ts falls back to.

Fixes the CI failure pattern observed on PR #13:
  Error: connect ECONNREFUSED 127.0.0.1:5432
  at Object.setup (src/tests/helpers/globalSetup.ts:25:22)

Credentials mirror the satrank/satrank/satrank default used locally so
we do not diverge test expectations between dev and CI. GitHub Actions
waits for the service healthcheck to pass before starting the job
steps, so no external wait-for-it script is needed.

* chore(sdk): normalize package.json repository.url
@proofoftrust21 proofoftrust21 merged commit c02c264 into main Apr 22, 2026
2 checks passed
@proofoftrust21 proofoftrust21 deleted the phase-12c-ops branch April 22, 2026 07:38
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