Skip to content

feat(ticket-048): publish github event acquisition adapter without env fallbacks - #66

Open
tom-sapletta-com wants to merge 8 commits into
mainfrom
ticket/048-publish-event-log-adapter
Open

feat(ticket-048): publish github event acquisition adapter without env fallbacks#66
tom-sapletta-com wants to merge 8 commits into
mainfrom
ticket/048-publish-event-log-adapter

Conversation

@tom-sapletta-com

@tom-sapletta-com tom-sapletta-com commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Ticket: ticket-048
Correlation ID: todo2code-pr-66-ticket-048

Republishes ticket-047's GitHub acquisition adapter through a route CI governance accepts, and fixes the defect that made it unpublishable.

Why the previous attempt failed

PR #64 was rejected for three independent reasons, none of which make governance could show — that command compares the working tree to HEAD, while CI compares base..head:

Blocker Cause
GOV-INTENT-003 intent.json and the implementation landed in one commit; the plan must exist in a strictly earlier commit
GOV-TICKET-001 ticket-047 reached DONE before publication, and a closed ticket holds no authority over implementation paths
unownable path the .env.example follow-up touches a path no workstream owns, and .governance/manifest.json is hash-locked to the pinned upstream standard

The fix

The third blocker had a cause inside the adapter: scripts/github-event-log.mjs fell back to process.env.GITHUB_EVENT_PATH and process.env.GITHUB_REPOSITORY. verify:env scans scripts/** and turns every process.env read into an .env.example requirement — so an acquisition boundary that reads the environment cannot be published in this repository at all.

Both fallbacks are removed. This is a better boundary regardless of governance: a bounded acquisition step should take its input explicitly rather than inherit ambient process state. Input now resolves only from --event-path, --repository, or the payload's own repository.full_name, and a missing repository names the flag.

The other two blockers are addressed structurally: the branch is cut from the protected base (so .env.example never enters the diff), the plan sits in commit b82e10a and the implementation in 2a25976, and ticket-048 stays IN_PROGRESS / VALIDATION until this PR merges — not DONE beforehand, which is exactly what stranded ticket-047.

Changes

  • scripts/github-event-log.mjs — no process.env reads; flags required
  • test/workflow-validation.test.ts — new case sets both variables in the child environment and asserts the adapter fails closed, writes no output file, and never echoes the ambient repository value
  • docs/EVENT_LOG_DSL.md — required flags, deliberate absence of environment reads, and why that constraint exists
  • test/fixtures/event-log/v1/github-event-payloads.json — carried across unchanged
  • project/ticket-047/** — historical record carried across verbatim, including its explicit note that it never obtained Koru or Validator approval

.env.example, .governance/**, .github/workflows/** and src/** are untouched.

Verification

  • project/governance-check.sh --actor ci --base b8392f7 --head 2a25976GOV-PASS, the check PR feat(ticket-047): add github event acquisition event log adapter #64 could not pass
  • make governance — GOV-PASS (0 errors, 0 warnings)
  • make verify — 402 tests, 401 pass, 1 skip, 0 fail
  • npm run verify:env — passes with .env.example byte-identical to origin/main
  • make docker-smoke — PASS
  • git diff --check — clean

Known gap

CHANGELOG.md gets no entry: like .env.example, it is owned by no workstream, so no ticket can edit it. That is the same trap this PR removes for .env.example, and it remains open for a future governance ticket.

🤖 Generated with Claude Code

tom-sapletta-com and others added 3 commits August 6, 2026 10:08
…ance

Plan-only commit. Declares the republication route for ticket-047's adapter and
the removal of its two process.env fallbacks, whose verify:env requirement
forced an edit to .env.example — a path no workstream owns and that the
hash-locked manifest cannot be extended to cover.

Carries the ticket-047 record across unchanged, including its explicit note
that no Koru review or Validator attestation was obtained.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…v fallbacks

Republishes ticket-047's bounded GitHub acquisition adapter through a route CI
governance accepts, and removes the defect that made it unpublishable.

The adapter previously fell back to process.env.GITHUB_EVENT_PATH and
process.env.GITHUB_REPOSITORY. verify:env scans scripts/** and turns every
process.env read into an .env.example requirement, but .env.example is owned by
no workstream and .governance/manifest.json is hash-locked to the pinned
upstream standard, so no ticket could legally declare those keys.

Both fallbacks are gone. Input resolves only from --event-path, --repository or
the payload's own repository.full_name, and a missing repository now names the
flag. A new case sets both variables in the child environment and asserts the
adapter still fails closed, writes no output and never echoes the ambient
value.

verify:env passes with .env.example byte-identical to the protected base.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every emitted event recorded SOURCE "github-api", carried over from ticket-047.
The adapter makes no API call: it reads a payload delivered by GitHub Actions,
and its own ticket declares API polling a non-goal. Claiming API provenance
contradicts the contract rule that missing knowledge is never guessed.

All four mappings now record SOURCE "github-actions", a value already
established in the ticket-045 golden fixture. The ambient-environment case
asserts it on every emitted event.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tom-sapletta-com

Copy link
Copy Markdown
Contributor Author

Added 95a4d91 after a pre-review audit.

Defect found in the carried-over ticket-047 code: every emitted event recorded SOURCE "github-api", but the adapter never calls the API — it reads a payload delivered by GitHub Actions, and intent.json lists API polling as a non-goal. Recording provenance the producer does not have contradicts the contract's own rule that missing knowledge is never guessed.

All four mappings now record SOURCE "github-actions", a value already established in the ticket-045 golden fixture, and the ambient-environment case asserts it on every emitted event. AC-04 was reworded to state this deviation from ticket-047 rather than claim identical behavior.

Also audited the diff for secret-shaped literals, since the Validator rejected #62 for a token= pattern. None present: the negative fixture uses a plainly descriptive string.

Re-verified at 95a4d91: CI-equivalent governance GOV-PASS, make verify 402 tests / 401 pass / 0 fail, verify:env passes with .env.example byte-identical to the base, docker-smoke PASS, and the documented invocation checked end-to-end against a real payload.

@tom-sapletta-com

Copy link
Copy Markdown
Contributor Author

Autonomy path (validator)

Root cause of no bot review: scan-direct is not on main yet — it lives in subactor/validator-agent#8. Repo variables DIRECT_PR_SCAN_ENABLED / DIRECT_PR_SCAN_CONFIG alone cannot trigger reviews until that job lands and semcod/todo2code is in the matrix.

Actions taken:

  1. Confirmed variables are set and complete (including todo2code checks on main).
  2. Added semcod/todo2code to the scan matrix + config on validator-agent PR fix(linker): restore raw similarity scoring #8 (8cf40bf).
  3. Dispatched direct-pr dry-run for this PR at head 95a4d91e94862b9d745422341aceb8368e0a0cae (ticket-048 / correlation todo2code-pr-66-ticket-048). Live approval follows if dry-run is clean.

Trust root preserved: reviewer is still outside the reviewed repository; todo2code never triggers its own approval.

…n note

Document that PR #66 is blocked only on trusted approval, point at the
ticket-049 plan branch for operator/refactor work, and note that CI wiring of
the adapter is deferred without collapsing the external Validator trust root.
Empty commit only. No product change. Previous verify/governance jobs
failed resolving action download info (Service Unavailable).
Link external twin-probes / validator-agent docs so operators know where
publication.gate and GOV-APPROVAL tooling live.
@tom-sapletta-com

Copy link
Copy Markdown
Contributor Author

Autonomy status (automated)

Item State
Head c7ce179
Product (local) build + acquisition tests green
koru / code-review success on this head
verify / Java still queuedGitHub Actions major_outage
Validator App review none yet (correct: requires green required checks)
Merge BLOCKED on GOV-APPROVAL + incomplete checks

Do not push further commits while freeze is pending.

When Actions recovers, operators should run:

~/github/subactor/validator-agent/bin/dispatch-direct-pr.sh \
  --owner semcod --name todo2code --pr 66 --ticket ticket-048 \
  --wait-checks --watch

Diagnosis probe: publication.gate in subactor/twin-probes (see docs/PUBLICATION_PROBE.md / docs/ECOSYSTEM.md).

The previous note blamed a missing scan-direct job in validator-agent main.
Both halves were re-checked and neither holds: the scan variables are set with
a semcod/todo2code entry, and scan-direct is present on validator-agent
origin/main.

The gate job test recorded zero steps and was cancelled after 23 minutes, so
validate and scan-direct were skipped — it never obtained a runner. The backlog
spans all six workflows in that repository while semcod/todo2code drains
normally.

The autonomy configuration is correct; the executor is starved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tom-sapletta-com added a commit that referenced this pull request Aug 6, 2026
Conditions 1-8 of steady-state autonomy all held for PR #66 on 2026-08-06 and
no review appeared. Adds precondition 9: the validator run must actually obtain
a runner.

Records the zero-steps signature — a job with no steps that is then cancelled
never started — as the way to tell an infrastructure stall from a validator
rejection, which always produces steps and a verdict.

Also warns against the inference this section originally drew: during an
Actions major_outage an uneven backlog is not evidence of an organization
budget problem, because a repository that keeps draining is not a control
group.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…dget

The previous commit blamed an Actions capacity or spending limit in the
subactor organization, reasoning that semcod/todo2code kept draining. That
inference was wrong: status.github.com reported Actions in major_outage, and
during an outage repositories stall unevenly, so one that keeps draining is not
a control group.

The observation that stands is the zero-steps signature: the gate job recorded
no steps and was cancelled, so it never obtained a runner. Analysis lives in
ticket-049 2.2.1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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