Feat/oss port flow#5
Open
fxck wants to merge 11 commits into
Open
Conversation
…e slot
Autonomous OSS "port" workflow, phase 0 (zero-deploy classification only):
- workflow/port_recon.go: ReconClassify(target descriptor, schema) -> PortPlan —
acquisition strategy (source-build/prebuilt-binary/crane-image-lift/bail),
dep->managed-catalog mapping, feasibility band. Image-only is IN-band via
crane-lift; only K8s-runtime-orchestration bails.
- workflow/port_session.go: PortSession sidecar (.zcp/state/port/{pid}.json),
mirrors work_session.go conventions, wraps WorkSession.
- PhasePortActive wired into build_plan.go empty-Plan fall-through (peer to
export/launch-production); tools/workflow_port.go handlePortStart serves
zerops_workflow workflow=port action=start.
TDD: table tests for recon decision tree (image->crane, k8s->bail, dep mapping
incl. clickhouse/kafka managed, band roll-up) + PortSession round-trip + handler.
go build ./... + go test ./internal/workflow ./internal/tools + make lint-local green.
Plan: plans/oss-recipe-port-flow-2026-06-09.md §8 Phase 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ecovery
Agent-driven port loop (handler derives, agent applies, handler records):
- workflow/port_fixclass.go: pure DeriveFixClass(FailureClass, signals) -> guidance.
build+command-not-found→prepareCommands; build+oom-killed→ESCALATE (not a fix —
build resources aren't import-tunable); start+db-refused→wire ${dep_*};
missing-env→EnvSet; migration→run.initCommands + zsc execOnce --retryUntilSuccessful;
config→glue zerops.yaml; credential→git-push-setup; network→retry. Prefers
glue-yaml over import edits; flags the import-override tax (ErrDiagnosisRequired
from iter 2 + state wipe) when an existing-hostname import edit is unavoidable.
- workflow/port_status_recovery.go: BuildPortActiveRecovery — PhasePortActive has an
empty Plan (peer to launch-production), so it gets its own recovery envelope (OQ-5).
- tools/workflow_port_iterate.go: handlePortIterate (reads FailureClassification
FIRST, derives fix-class, records attempt) + handlePortStatus; routed via
routePortAction (single pre-switch dispatcher, keeps handleWorkflowAction under
the maintidx/cyclo lint thresholds).
Low blast radius: failure signals persist on the port-owned PortSession.Attempts
(new PortAttempt type + RecordPortAttempt); shared work_session.go DeployAttempt is
UNTOUCHED (its tests stay green). Phase 2 reads Attempts for stall detection.
TDD: fix-class table, iterate round-trip, status recovery, work-session-untouched
guard. go build + go test ./internal/{workflow,tools} + TestArchitectureLayering +
make lint-local all green.
Plan: plans/oss-recipe-port-flow-2026-06-09.md §8 Phase 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pure logic over PortSession.Attempts (no live ops): - workflow/port_progress.go: three terminators — two-counter stall detection (classStallStreak keys on FailureClass CATEGORY so it survives Signals variation; phaseStallStreak on fix-class phase non-advancement, with a progressRose seam for Phase 3 tier-rise), iteration cap per band (EASY 4/MEDIUM 8/HARD 12) closing the wrapped session with the existing CloseReasonIterationCap, wall budget (time injected). EvaluatePortProgress rolls them up; cap measured from RebudgetOrigin. - workflow/port_escalate.go: T0 stay / T1 source-build→prebuilt (classStall>=3 on build or OOM-flag, AND a PrebuiltURL exists, still on source-build) / T2 bail; credential+network never escalate. - iterate handler wires the decision: T1 mutates Plan.Acquisition + re-budgets; any terminator stops (cap → idempotent close guarded on CloseReason, not raw ClosedAt — P5 TestNoRawClosedAtReads); T0 returns the fix guidance. Adds PortPlan.PrebuiltURL + PortSession.RebudgetOrigin. work_session.go untouched. TDD: classStall-survives-signal-variation, phaseStall trip/reset, cap+close, T1-only-with-prebuilt, credential/network-no-escalate, wall budget. build + tests + TestArchitectureLayering + TestNoRawClosedAtReads + make lint-local green. Plan: plans/oss-recipe-port-flow-2026-06-09.md §8 Phase 2 (§4 mechanics). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
docs/spec-oss-port-flow.md — the runtime/architecture reference (distinct from the build plan): two-stage model (port&harden → capture), agent-driven loop, recon + acquisition ladder (incl. crane image-lift), fix-class dispatch, two-counter termination + T0/T1/T2 escalation, rubric→FitCeiling, the curated publish channel (zerops-recipe-apps + zeropsio/recipes, NOT .zerops-recipe/), feasibility bands + the PostHog reality, and implementation status (Phases 0-2 built, 3-5 designed). Pointer added to CLAUDE.md key specs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… plan Design artifacts the feat/oss-port-flow commits reference: the port-flow plan (plan of record), its independent verification verdict, and the superseded software-shape plan (kept for D4/D6 + verified contract facts). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Scores how well the ported software runs; logic unit-tested, live harden deferred: - workflow/port_rubric.go: C1 builds / C2 boots-STABLE (ACTIVE-then-exit→1, stable→2) / C3 serves / C4 core-flow / C5 persists / C6 HA (throughput=1 vs HA-replication=2, MEMORY invariant). Port-local PortTierLevel enum (6 levels) — NO recipe.Tiers() import (depguard-clean; Break #1 resolved); recipe.TierAt re-derived at Phase 4 emit. - workflow/port_fitceiling.go: FitCeiling + pure BuildFitCeiling — highest-honored-tier projection; a tier is honored only if prereqs met (C5=2,C6=1 ⇒ tiers 0-4, tier 5 excluded with reason; C1=C2=C3=0 ⇒ infeasible). Measured ceiling vs recon band both kept. - workflow/port_harden.go: PlanHarden (durable-surface sentinel plan + HA scale probe) + pure GradeHarden(injected results) → C5/C6. No ops calls in workflow. - tools/workflow_port_harden.go: agent-driven "harden" action — emits sentinel/scale guidance, grades agent-reported results, builds + persists FitCeiling on PortSession. - progressRose wired: EvaluatePortProgress(ps, now, progressRose); a rising measured ceiling breaks phaseStall (the Phase 2 seam). iterate attaches FitCeiling at stop/bail. TDD: each C grade, roll-up incl. tier5-not-honored + infeasible, rose-breaks-phaseStall, harden grading from mocks, FitCeiling shape + reasons. build + tests + TestArchitectureLayering (no workflow→recipe) + make lint-local green. work_session untouched. Plan: plans/oss-recipe-port-flow-2026-06-09.md §5 + §8 Phase 3. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stage B: turn the working ported deployment into a curated recipe. First (additive)
touch of internal/recipe; framework emit path byte-identical (goldens unchanged).
- recipe/yaml_emitter.go: D6 buildFromGit override at BOTH emit sites — runtime
(writeRuntimeBuildFromGit) AND the ServiceKindUtility branch (which emitted none).
Emits Plan.GlueRepoURL verbatim (canonicalized via topology.CanonicalRepoURL) when
set; falls back to the hardcoded RecipeAppRepoBase form when empty. recipe/plan.go:
Plan.GlueRepoURL (omitempty). recipe/assemble.go: exported SubstituteFragmentMarkers.
- tools/workflow_port_capture.go: handlePortCapture (action "capture") — gated on
FitCeiling.Feasible; portSessionToPlan maps the working topology + honored-tier
subset + glue URL into a *recipe.Plan; emits environments/<N — Name>/{import.yaml,
README.md} via EmitDeliverableYAML + recipe.TierAt for honored tiers ONLY; authors
rich content (description/features/takeover-guide/knowledge-base from FitCeiling
evidence + UnresolvedConstraints) via the existing marker machinery; publishes app→
zerops-recipe-apps + envs→zeropsio/recipes via direct sync calls (portPublisher
seam, initialized var). BuildFromGitReady=false → defers publish, never fails (OQ-1).
Grounding: D4 recipe-level fragment SURFACES not needed — curated rich content rides
the existing marker machinery + publish flags + Strapi, same as framework recipes.
TDD: GlueRepoOverride (both sites; empty→hardcoded), PortSessionToPlan honored-subset,
capture feasible/infeasible/not-scored/glue-not-ready. Existing recipe suite
(TestYAMLEmitter_MatchesFixture etc.) stays green = framework path unchanged.
build + recipe/workflow/tools/sync tests + TestArchitectureLayering +
TestNoCrossCallHandlerState + make lint-local green.
Plan: plans/oss-recipe-port-flow-2026-06-09.md §8 Phase 4. Spec status bumped to 0-4.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Finisher, using the CORRECTED PostHog reality (plan §12): PostHog is fully feasible INCLUDING HA — the honest residue is knowledge depth, not infeasibility. - port_recon.go: cross-service-ordering axis (PortTargetDescriptor.CrossServiceOrdering) — forces BandHard and records the IN-BAND fix (zsc execOnce --retryUntilSuccessful + zsc scale ram max), never a bail. Acquisition untouched (image-only stays crane-lift). - workflow_port_capture.go: HARD-band honesty content — hardBandChoreographyNote injects the retry-until-ready choreography into the knowledge-base + takeover-guide fragments for BandHard ports; UnresolvedConstraints (Kafka SASL prefixes, Fernet key, ioredis URL, patched Rust fork) surfaced as the honest residue. - PostHog canonical HARD fixture (server-level recon→harden→FitCeiling→capture, real embedded catalog): crane-lift, all deps managed incl. ClickHouse HA, C5=2 + C6=2 → Tier 5 (ha-prod) HONORED (explicitly asserts NOT infeasible, NOT Tier5-dropped) — the §12 correction pinned. Strapi EASY contrast fixture confirms no HARD-band noise. TDD: cross-service-ordering raises-band-not-bail, image-only-stays-crane, PostHog honest contract, HARD-band choreography in fragments + EASY no-leak. build + recipe/workflow/ tools suites + TestArchitectureLayering + make lint-local green. Framework path unchanged. Note: pre-existing flaky test TestDeployIntoDerivedClosedSession_SucceedsAndRecords (session-deploy timing, unrelated to port) — port tests are deterministic (5x green). Plan: plans/oss-recipe-port-flow-2026-06-09.md §8 Phase 5. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ntegration Two test files were left unstaged in their phase commits (impl + unit tests landed, these did not): - recipe/yaml_emitter_test.go: TestEmitDeliverableYAML_GlueRepoOverride — pins D6 (override at runtime + utility emit sites, canonicalized; framework path byte-identical when GlueRepoURL empty). Without this, Phase 4's D6 was unpinned. - tools/workflow_port_iterate_test.go: Phase 2 handler-level integration — iteration-cap closes+stops, build-stall T1 escalation sets RebudgetOrigin, no-prebuilt bails. Both pass; no impl change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sentinel Codex-validated fixes to the OSS port-flow feasibility/band model (4 review rounds → SHIP). Each finding traced to a real defect, not just a weak test. - C2 gate requires grade 2 (boots STABLE): a crash-loop / ACTIVE-then-exit (C2=1) honors NO tier and lands in WhatDoesnt, never WhatRuns. Pinned by TestRollUpHonoredTiers_C2CrashLoopFailsGate + TestBuildFitCeiling_C2CrashLoopNotInWhatRuns. - Infeasible FitCeiling reports MeasuredCeiling = PortTierNone (-1), distinct from honored Tier 0, so a consumer ignoring Feasible can't misread it. - Port emits MEASURED HA topology, not capability-table assumptions: the agent reports per-dep haDeps; DeriveAchievableHA filters to planned mode-bearing deps (storage excluded); the C6 grade AND the emitted per-service mode both consume the same ManagedHADeps list, so they cannot diverge. ClickHouse emits HA (mandatory for PostHog ON CLUSTER DDL), Postgres/Valkey NON_HA — matching the real recipe-posthog. Driven by additive recipe.Service.ModeMeasured + the single-owner recipe.ManagedServiceModeForTier; framework emit path is byte-identical (ModeMeasured=false keeps the run-12 §Y3 family-table logic). - managedTypeFor resolves bare types (strip :ha/:single) so the emitter owns mode via the mode: field, not a composite type token. clickhouse added to the HA family table (proven HA on Zerops). - Cleanups: dead constraints counter, stale Phase-5 plan row, doc/logic mismatch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
krls2020
added a commit
that referenced
this pull request
Jun 15, 2026
docs/spec-authoring-boundary.md is the living truth: what lives inside the domain (+ the OSS-port flow's documented future home and handler rules), the L1-L4 laws with their depguard/test pins, the C1-C6 runtime contract list, gate semantics, ownership-by-path, and operational notes (Aleš's env, flow-eval env propagation). CLAUDE.md gains the boundary invariant bullet + updated dependency table; the architecture spec's per-package row and the content-surface/rubric spec paths follow the move. v2-remnant retirement is backlogged with inventory + promote trigger (plans/backlog/v2-recipe-remnants.md); both plan docs archive with a deviations ledger (P4 moot — PR #5 will not merge; atom-vars check stays in authoring/analyze because its subject is authoring content). Plan: plans/archive/authoring-boundary-2026-06-11.md (P5)
krls2020
added a commit
that referenced
this pull request
Jun 15, 2026
… override + measured-mode emission Recipe-side hunks of the PR #5 (feat/oss-port-flow) integration, applied onto the moved internal/authoring/recipe path: - Plan.GlueRepoURL: per-plan buildFromGit override for the OSS port flow's single self-referential glue repo — BOTH emit sites (runtime + the ServiceKindUtility branch), canonicalized via topology.CanonicalRepoURL. Framework path (empty) stays byte-identical. - Service.ModeMeasured + ManagedServiceModeForTier: single mode-resolution owner for the two emit sites; a port-MEASURED service emits its measured mode verbatim (no family-table force-promotion at tier 5), framework services keep the run-12 §Y3 family-table behavior. - clickhouse joins the HA-capable family table (proven by fxck/recipe-posthog — mandatory for PostHog's ON CLUSTER DDL). - SubstituteFragmentMarkers exported for the port capture stage (pure re-export); doc comments unglued from the unexported worker. Pinned by TestEmitDeliverableYAML_GlueRepoOverride, TestManagedServiceModeForTier, TestManagedServiceSupportsHA_FamilyTable.
krls2020
added a commit
that referenced
this pull request
Jun 15, 2026
…ntegration) Full integration of PR #5 (feat/oss-port-flow, never merged), reshaped to the authoring boundary's prescribed Future-home shape: the whole flow lives in internal/authoring/port/ as a self-registering ZCP_AUTHORING-gated MCP tool (recipe.Register model) — NOT a workflow= value, NO WorkflowInput fields, NO core envelope phase. Semantics preserved 1:1 from the PR. Engine (recon / fixclass / rubric / fitceiling / harden / progress / escalate + tests) transplanted verbatim — it was already boundary-clean (schema + topology only). Two redesigns where the PR coupled to core: - PortSession is STANDALONE (the PR wrapped workflow.WorkSession): own ProjectID/Environment/Intent/ClosedAt/CloseReason fields, own attempt recording, terminal iteration-cap close (CloseReason-guarded). Identity and time split into two fields — StartTime is an opaque process-instance token (recycled-PID guard, now actually CHECKED on load; the PR stored it but never verified), CreatedAt is the RFC3339 wall-budget anchor. The PR anchored the wall budget on the process-identity field, which is unparseable proc-ticks on Linux — the terminator could never fire there. - Status recovery is the tool's own envelope (kind/tool/phase/nextCall → zerops_port action=iterate), not a core Phase. Tool layer rewritten from internal/tools/workflow_port*.go into the port package: PortInput (de-prefixed fields: target, failureClass, signals, deploySucceeded, importOverride, rubric, glueRepo, unresolved, publishDryRun), own FlexBool + error wire (code/error/suggestion/recovery vocabulary, recovery → zerops_port status), schema derivation with FlexBool oneOf patching across the nested input tree. Capture rewired: recipe emit verbs → authoring/recipe, curated publish → authoring/publish.{CreateRecipeRepo,PushAppSource,Recipe} over the core-sync config surface (C5). Boundary mechanics in the same commit (the deliberate-contract-change rule): depguard authoring-allowlist admits jsonschema-go (the mcp go-sdk's own schema vocabulary — mcp.Tool.InputSchema IS *jsonschema.Schema) + spec L2 row updated; C3 state-namespace contract now PINNED by TestAuthoringBoundary_StateNamespaces (AST scan of every filepath.Join(stateDir, …) site — authoring owns port/ + port-recipes/, core owns the rest) with scanner self-test; TestNoCrossCallHandlerState roots include authoring/port; server registers port.Register inside the gate; TestServer_AuthoringToolsRegistered + TestAnnotations_AuthoringTools* cover zerops_port.
krls2020
added a commit
that referenced
this pull request
Jun 15, 2026
…<OSS> recipe' reaches zerops_port - docs/spec-oss-port-flow.md: the runtime/architecture reference adopted from PR #5 and rewritten for the shipped shape (gated zerops_port tool in internal/authoring/port/, standalone session, tool-owned status recovery; no workflow=port, no PhasePortActive). Status: shipped 2026-06-12; remaining live e2e verification + OQ-1 noted. - agents_authoring.md (gated AGENTS.md block): trigger routing the PR never had — 'create umami recipe' / 'port strapi' on third-party OSS routes to zerops_port; zerops_recipe stays the framework-showcase tool. Without this, zerops_recipe swallowed foreign-OSS prompts and authored them from scratch (observed on the eval container). Pinned by TestBuildAgentsMD_AuthoringGate + TestAgentsShared_NoAuthoringLeak. - CLAUDE.md key-specs line + authoring-domain mentions updated (port flow shipped, no longer 'future'). - plans/archive/: the three PR #5 design docs archived verbatim (banner on the main plan notes the reshaped landing).
krls2020
added a commit
that referenced
this pull request
Jun 15, 2026
…zcprecipator2 + dead refs Completes the 'as if v2 never existed' sweep on top of the v2 analyze-harness retirement: - internal/authoring/recipe/verify.go — DELETED. 104 lines of HTTP verification primitives (DefaultVerifier/ReachableHTTP/HealthEndpoint/...) introduced by the recipe Phase-2a engine (2b437d3), never wired into the v3 engine, zero callers anywhere (prod or test). Not a PR #5 artifact (the port flow delegates C3 'serves HTTP' to core zerops_verify). deadcode -test ./... is now ZERO across the whole tree. - docs/zcprecipator2/ — DELETED (214 files, 4.5M). The v2 design + run corpus; no Go code embeds or reads it (build-unaffected), no live spec/CLAUDE.md references it. Recoverable from git history. - docs/zcprecipator3/ — the dead '../zcprecipator2/' markdown links neutralized to plain prose (follow-the-chain: no broken links left) and the 'v2 archaeology lives in ../zcprecipator2/' location statements corrected to 'removed; in git history'. The v2-comparison NARRATIVE (the legitimate 'why v3 exists' design rationale) is kept — it is design history, not a remnant. - .golangci.yaml — the analyze tagliatelle exclusion comment rewritten: its v2 justification (spec-defined B-15_* snake_case keys) is gone; the real current reason is the v3 harness parsing external session-log records whose source key input.file_path is snake_case (must match byte-for-byte). - internal/content/repo_drift_test.go — removed the now-dead skip entry for the deleted internal/content/workflows/recipe tree. Live code + config now carry ZERO references to any deleted v2 path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.