Skip to content

ci(decisions): reconcile the Current Decisions pages with a scheduled job - #3795

Open
migmartri wants to merge 3 commits into
chainloop-dev:mainfrom
migmartri:ci/decisions-reconcile
Open

migmartri wants to merge 3 commits into
chainloop-dev:mainfrom
migmartri:ci/decisions-reconcile

Conversation

@migmartri

@migmartri migmartri commented Nov 7, 2026 •

Copy link
Copy Markdown
Member

Add a GitHub Actions job that keeps the Current Decisions pages (docs/decisions/) up to date. It ports chainloop-dev/platform#7115 to this repository, with the fixes of chainloop-dev/platform#7178 and chainloop-dev/platform#7194.

The job runs the eng-adr reconcile skill of chainloop-dev/brain with claude-code-action, in the skill's scheduled mode: it asks no questions, writes only the changes that need no person, and lists the open questions in the PR body. When the pages change, it opens or updates one draft PR on the decisions-reconcile-scheduled branch. When nothing changes, it opens no PR. The PR has the title adr: update YYYY-MM-DD (UTC date of the run) and the labels automated and skip-ai-session.

The job runs at 05:00 UTC from Monday to Friday, and can be started manually with an optional area. A manual run is a dry run by default: it uploads the diff and the PR body as an artifact.

  • Claude authenticates with workload identity federation (no Anthropic API key).
  • Claude gets read-only GitHub tokens. It reads the states of the GitHub issues of the specs through the collector, with the job token. The job fails when Claude changes a file outside docs/decisions/ and CLAUDE.md.
  • The chainloop-eng GitHub App commits, pushes and opens the PR.

The job fails, and never reports "no change", when the run is not complete:

  • "Check sources" runs before Claude. It reads one issue and the pull requests of the repository with the job token, checks that the brain plugin has skills/eng-adr/SKILL.md, and runs the collector decisions.py on the checkout.
  • Claude stops and writes source-error.txt when a call to GitHub or the collector fails or is refused. "Check Claude run" fails when that file exists.
  • Subagents run in the foreground (CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1). A headless run ends with Claude's turn, so a background subagent's result is lost. Claude writes done.txt as its last action, and "Check Claude run" fails without it.
  • The Claude output is uploaded after each run, to show what a run did.

The prompt names the skill steps by title, and lists the changes that need no person and the changes that need a person.

Differences from the platform version:

  • The job runs only on chainloop-dev/chainloop, not on forks.
  • The federation rule ID comes from the repository variable ANTHROPIC_FEDERATION_RULE_ID, because the platform rule is restricted to the platform repository.
  • No Linear. The specs of this repository use GitHub issues.
  • The workflow grants permissions per job (with issues: read), and the write token is limited to this repository.
  • The bot commits are signed (sign-commits) and carry an Assisted-by: Claude Code trailer, as this repository requires.

Setup before the first run:

  • Create a federation rule restricted to repo:chainloop-dev/chainloop:ref:refs/heads/main and set its ID in the variable ANTHROPIC_FEDERATION_RULE_ID.
  • Add the secret CHAINLOOP_ENG_APP_PRIVATE_KEY.
  • Install the chainloop-eng app on chainloop (contents and pull requests: write) and brain (contents: read).

AI disclosure: this change was written with Claude Code.

View guided diff

@chainloop-platform

chainloop-platform Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

PR validation — ⚠️ 1 failing

Status Policy Material Messages
⚠️ Failed pr-min-approvals pr-info PR/MR #3795 has 0 approving reviews, 1 required.
✅ Passed pr-description-required pr-info -
✅ Passed pr-user-story-linked pr-info -

View attestation ↗

AI Session Checks — 🟡 71% · ⚠️ 2 failing

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🟡 71% 2 ⚠️ 2 98% AI / 2% Human 1 +356 / -32 61h3m43s

🟡 60% — 100% AI — ⚠️ 1 policies failing

Nov 7, 2026 07:54 UTC · 10m51s · $2.66 · 70 in / 36.6k out · claude-code 2.1.319 (claude-opus-5-5)

View session details ↗

Change Summary

Adds scheduled and manual reconciliation of Current Decisions pages with dry-run artifacts and draft-PR publishing. Adapts repository-specific authentication, fork guards, commit policy, and credential scope.

AI Session Overall Score

🟡 60% — The focused workflow port needs target-runtime validation and review of checkout and dependency boundaries.

AI Session Analysis Breakdown

🟢 96% · scope-discipline

🟢 The final diff adds only the requested workflow; review fixes do not touch decision pages or unrelated code. · High Impact

🟢 90% · context-and-planning

No notes.

🟢 86% · user-trust-signal

No notes.

🟡 76% · alignment

🟢 The completion report distinguishes successful syntax parsing from unavailable linting and unexecuted runtime validation. · High Impact

🟠 Manual dispatch can select another branch because checkout omits main and the job lacks a main-ref guard. · Medium Severity

💡 Pin the checkout ref and align dispatch restrictions with federation restrictions before describing every run as main-based.

🟡 76% · solution-quality

🟢 Review fixes narrow write credentials to the target repository and move token-minting permission into the sole required job. · High Impact

🟠 The AI retained a moving plugin checkout, allowing executable reconciliation behavior to change without a reviewed workflow update. · Medium Severity

💡 Pin executable plugin dependencies to reviewed commits and verify the checkout before invoking them.

🔴 38% · verification

🔴 Only syntax parsing ran for the target workflow; source-repository success does not validate adapted authentication or publishing. · High Severity

💡 After prerequisites are configured, dispatch a target-repository dry run and inspect its authentication, change guards, and artifact outputs before merging.


File Attribution

████████████████████ 100% AI / 0% Human

Status Attribution File Lines
created ai .github/workflows/decisions_reconcile.yml +264 / -0

Policies (4, 1 failing)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-f2be09 -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-f2be09 -
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-f2be09 -
⚠️ Failed ai-config-no-secrets ai-coding-session-f2be09
  • Secret (linear-client-secret) detected in session content [turn=161, source=tool_result, line=1]: {"body":"\u003c!-- chainloop-pr-analysis:v1 --\u003e\n## PR validation — ⚠️ 1 failing\n\n| Status | Policy | Material | Messages |\n| --- | --- | --- | --- |\n| ⚠️ Failed | [pr-min-approvals](https:...
  • Secret (linear-client-secret) detected in session content [turn=196, source=assistant-tool_use:Bash, line=22]: LINEAR_CLIENT_ID: [CHAINLOOP_TRACE_REDACTED:linear-client-secret]
  • Secret (linear-client-secret) detected in session content [turn=41, source=tool_result, line=106]: + LINEAR_CLIENT_ID: [CHAINLOOP_TRACE_REDACTED:linear-client-secret]
  • Secret (linear-client-secret) detected in session content [turn=92, source=assistant-tool_use:Write, line=1]: {"content":"# =============================================================================\n# Reconcile of the Current Decisions pages (docs/decisions/)\n# ===========================================...

🟢 83% — 96% AI — ⚠️ 1 policies failing

Nov 7, 2026 16:04 UTC · 60h52m52s · $14.35 · 530 in / 160.5k out · claude-code 2.1.319 (claude-opus-5-5)

View session details ↗

Change Summary

Makes the reconciliation wait for delegated work before finishing. Adds a completion marker and rejects runs that end without it.

AI Session Overall Score

🟢 83% — Focused root-cause fix with transparent reporting; live completion behavior remains unverified.

AI Session Analysis Breakdown

🟢 95% · scope-discipline

No notes.

🟢 90% · alignment

🟢 The assistant explicitly limits its completion report to syntax checks and defers live behavior confirmation. · High Impact

🟢 90% · context-and-planning

No notes.

🟢 90% · solution-quality

🟢 The assistant inspects captured execution output showing unfinished workers and unwritten pages before changing completion behavior. · High Impact

🟢 The added completion guard fails explicitly when the marker is absent, rather than masking premature termination as no change. · High Impact

🟢 90% · user-trust-signal

No notes.

🟡 60% · verification

🟠 The new completion behavior was not exercised; the assistant provides a post-merge test recipe, with no subsequent user confirmation. · Medium Severity

💡 Run the updated reconciliation and verify page changes and incomplete-run rejection before treating the fix as validated.


File Attribution

███████████████████░ 96% AI / 4% Human

Status Attribution File Lines
modified ai .github/workflows/decisions_reconcile.yml +92 / -32

Policies (4, 1 failing)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-c9e9a4 -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-c9e9a4 -
⚠️ Failed ai-config-no-secrets ai-coding-session-c9e9a4
  • Secret (linear-client-secret) detected in session content [turn=106, source=tool_result, line=99]: LINEAR_CLIENT_ID: [CHAINLOOP_TRACE_REDACTED:linear-client-secret]
  • Secret (linear-client-secret) detected in session content [turn=168, source=tool_result, line=30]: 1544:2026-11-07T08:02:32.3787536Z LINEAR_CLIENT_ID: [CHAINLOOP_TRACE_REDACTED:linear-client-secret]
  • Secret (linear-client-secret) detected in session content [turn=246, source=assistant-tool_use:Edit, line=1]: {"file_path":"/tmp/claude-1000/-home-migmartri-work-chainloop-brain/c9e9a4d6-7acf-4c96-a8a8-850e7f6d89aa/scratchpad/platform/.github/workflows/decisions_reconcile.yml","new_string":" - name: Chec...
  • Secret (linear-client-secret) detected in session content [turn=27, source=tool_result, line=235]: - LINEAR_CLIENT_ID: [CHAINLOOP_TRACE_REDACTED:linear-client-secret]
  • Secret (linear-client-secret) detected in session content [turn=36, source=tool_result, line=104]: 104 LINEAR_CLIENT_ID: [CHAINLOOP_TRACE_REDACTED:linear-client-secret]
  • Secret (linear-client-secret) detected in session content [turn=481, source=assistant-text, line=5]: 1. Open https://linear.app/settings/applications/ and pick the app with client ID [CHAINLOOP_TRACE_REDACTED:linear-client-secret]. That's the one in your earlier screenshot.
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-c9e9a4 -

Security Checks — ⚠️ 1 failing

✅ Nothing this change touches re-opens a recorded security fix.

View in Chainloop ↗ · How this works ↗
✅ Nothing this change touches re-opens a recorded security fix.

View in Chainloop ↗ · How this works ↗

✅ secret-scan

Status Policy Messages
✅ Passed secrets-detection -

✅ github-actions-scan

Status Policy Messages
✅ Passed ci-pipeline-security -

✅ sast-scan

Status Policy Messages
✅ Passed owasp-top10-2025 -
✅ Passed sast -
✅ Passed cwe-top25 -
✅ Passed cwe-top26-40-cusp -

⚠️ iac-scan — 1 failing

Status Policy Messages
⚠️ Failed iac-misconfiguration The build output cannot be affected by user parameters other than the build entry point and the top-level source location. GitHub Actions workflow_dispatch inputs MUST be empty. in ".github/workflows/decisions_reconcile.yml" (error)
Scan not applied (1)
Scan Reason
vulnerability-scan no manifest/lockfile changed

View attestation ↗


Powered by Chainloop and Chainloop Trace

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/decisions_reconcile.yml">

<violation number="1" location=".github/workflows/decisions_reconcile.yml:83">
P1: The token steps pass a GitHub App client ID through `app-id`, which expects the numeric App ID; token generation will fail before the brain or repository token is available. Pass this value through `client-id` in both steps, or configure the numeric App ID.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

id: brain-token
uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2
with:
app-id: ${{ env.CHAINLOOP_ENG_APP_CLIENT_ID }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The token steps pass a GitHub App client ID through app-id, which expects the numeric App ID; token generation will fail before the brain or repository token is available. Pass this value through client-id in both steps, or configure the numeric App ID.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At .github/workflows/decisions_reconcile.yml, line 83:

<comment>The token steps pass a GitHub App client ID through `app-id`, which expects the numeric App ID; token generation will fail before the brain or repository token is available. Pass this value through `client-id` in both steps, or configure the numeric App ID.</comment>

<file context>
@@ -0,0 +1,260 @@
+        id: brain-token
+        uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2
+        with:
+          app-id: ${{ env.CHAINLOOP_ENG_APP_CLIENT_ID }}
+          private-key: ${{ secrets.CHAINLOOP_ENG_APP_PRIVATE_KEY }}
+          owner: chainloop-dev
</file context>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changed. GitHub accepts the client ID in place of the numeric App ID as the JWT issuer, and the pinned action passes the app-id value through to it. The same step with the same value succeeds in chainloop-dev/platform (run 42352738620, step "Generate brain read token"). The workflow now has a comment that says this.

@migmartri
migmartri requested a review from a team November 7, 2026 08:04
… job

Port of chainloop-dev/platform#7115. Runs the eng-adr reconcile skill with
claude-code-action on weekdays and on a manual start, and opens a draft PR
when docs/decisions/ changes.

Assisted-by: Claude Code
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>

Chainloop-Trace-Sessions: f2be09e9-dc71-42ed-9ac5-d843d16f9715
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
@migmartri
migmartri force-pushed the ci/decisions-reconcile branch from b0c0e7e to 2838d0f Compare November 7, 2026 08:05

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 1 file (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

jiparis
jiparis previously approved these changes Nov 9, 2026
…econcile job

Port the fixes of the platform reconcile job. A Check sources step reads
one issue and one pull request with the job token and runs the collector
before Claude starts. Claude runs subagents in the foreground, writes
source-error.txt when a source fails and done.txt as its last action, and
Check Claude run fails on either. The Claude output is uploaded after each
run. The prompt names the skill steps by title and lists which changes
need a person.

The parent tickets of the specs are GitHub issues, so the job no longer
gets a Linear token or the Linear MCP server, and gets issues: read.

Assisted-by: Claude Code
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Miguel Martinez <miguel@chainloop.dev>

Chainloop-Trace-Sessions: c9e9a4d6-7acf-4c96-a8a8-850e7f6d89aa
Add the automated and skip-ai-session labels to the reconcile PR, as on
the other automated PRs. The workflow sets the PR title to
"adr: update YYYY-MM-DD" (UTC date of the run), so each run has a
distinct title. Claude no longer writes the PR title.

Assisted-by: Claude Code
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
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.

2 participants