fix: harden kan-ductor agent safety gates #61
No reviewers
Labels
No labels
3plus3-followup
agent/claude-code
agent/codex
agent/hermes
agent/iskra
agent/ollama
agent/patchwarden
analytics
api
cockpit
dependency/blocked
dependency/blocks-others
dependency/cross-repo
dependency/needs-confirmation
docs
domain:agents
domain:ci
domain:docs
domain:forgejo
domain:infra
domain:memory
domain:runtime
domain:signal
domain:ux
flow/architecture
flow/blocked
flow/deployed
flow/done
flow/implementation
flow/intake
flow/maintained
flow/observed
flow/ready
flow/refining
flow/retired
flow/review
gemini-flash
judge/codex-candidate
judge/hermes-candidate
judge/low-confidence
judge/needs-refinement
judge/operator-needed
judge/p0
judge/p1
judge/p2
judge/p3
judge/park
judge/patchwarden-candidate
judge/stale-priority
kind/adr
kind/bug
kind/chore
kind/feature
kind/infra
kind/ops
kind/refactor
kind/research
leviathan
mcp
merge/auto
merge/manual
merge/manual-dependency-conflict
merge/manual-failing-tests
merge/manual-merge-conflict
merge/manual-missing-review
merge/manual-operator-preference
merge/manual-red-zone
merge/manual-security-sensitive
merge/manual-unclear-scope
merge/manual-unknown
mode:operator-only
mode:patchwarden-iskra-approved
mode:safe-auto
observed/erroring
observed/needs-followup
observed/pending
observed/retire-candidate
observed/unused
observed/used
ops
priority:p0
priority:p1
priority:p2
priority:p3
review:claude-reviewed
review:codex-reviewed
review:dziadek-reviewed
review:needs-human
safety
safety:external-write
safety:no-prod-mutation
safety:prod-impact
safety:secret-touch
scout
security
size/large
size/medium
size/small
size/tiny
size/unknown
small-task
source/adr
source/agent-generated
source/manual
source/operator-chat
source/voice-note
status:blocked
status:codex-ready
status:merged:pending-evidence
status:needs-evidence
status:operator-needed
status:parked
tests
tier:0-platform-substrate
tier:1-iskra-value-layer
tier:2-tools-products-modules
type:bug
type:chore
type:docs
type:feat
type:policy
type:research
ui
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
pdurlej/kan-ductor!61
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "codex/codex-kan-ductor-stabilization-codex"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Canary status: missing - fire 3+3 review before merge
Supersedes #60. #60 was created with the wrong Forgejo actor (
glm); this PR is pushed and owned bycodexperagent-soulsidentity discipline.Summary
Hardens the Kan-ductor maintainer layer after the Piotr + Iskra MCP smoke loop started working. This PR focuses on safety gates, audit truth, recap reliability, MCP readiness probes, and maintainer tooling.
Scope
projection:writeandprojection:override_warningsscopes.KAN_PROJECTION_APPLY_ENABLED=falsedefault for real Leviathan apply.activityPublicIdfor create/move/comment/relation actions.includeRaw=trueandworkspace:manage.getRecentActivity.summaryfor Piotr/Iskra recap questions./live,/ready, and readiness-compatible/healthto MCP._bmad-output/project-context.md.Non-goals
KAN_PROJECTION_APPLY_ENABLED=truein production.Spec sources read
docs/agent-mcp-contract.mddocs/leviathan-projection-contract.mddocs/openclaw-kan-mcp.md_bmad-output/project-context.mdagent-souls/AGENTS.mdidentity disciplineagent-souls/practices/credential-management.mdTests / smoke
Run locally:
Known repo-level lint caveats:
@kan/api lintstill reports pre-existing lint debt outside this PR scope.@kan/db lintstill reports pre-existing lint debt outside this PR scope.@kan/mcp lintcurrently lacks an eslint flat config in that package.Rollback
KAN_PROJECTION_APPLY_ENABLED=false.Owner gates
Piotr approval required before:
KAN_PROJECTION_APPLY_ENABLED=true,3+3 review request
Required before merge because this PR touches auth scopes, write gates, audit redaction, MCP readiness, schema enum migration, and drift/lineage semantics.
fix: harden kan-ductor agent safety gatesto WIP: fix: harden kan-ductor agent safety gates3+3 review triggered by Codex
Gate result: NOT READY / fail closed.
This review was run from the Codex Forgejo identity against draft PR #61. Context sent to cloud workers was redacted locally first; Signal-like phone refs and bearer/token-like values were removed before Ollama/Claude review.
Deterministic checks
diff_size, 1699 changed lines >= 500pnpm --filter @kan/api test -- agent.test.ts=> 20 passedpnpm --filter @kan/mcp test -- health.test.ts=> 1 passedReviewer verdicts
Merge blockers I would fix before moving this out of draft
Relation idempotency replay is not input-bound.
performLinkCardRelation/performUnlinkCardRelationreplay by token + action + idempotency key only. Reusing the same key with a different relation payload can return the old result silently. Add input hash or conflict check.Low-confidence attribution is still too easy to treat as canonical.
Exact
activityPublicIdlineage is good, but time-window fallback still presents as agent-attributed withconfidence: low. Summaries should split exact vs low, and docs should say low cannot authorize projection apply or canonical “Iskra did X” claims.Projection apply audit should preserve warning codes structurally.
Batch audit currently stores summary/results, but not a first-class
warningCodes/ override record. For audit-as-product-soul, warning override needs structured reconstruction.Projection apply batch idempotency is requestId-derived.
The batch audit idempotency key uses
ctx.requestId, so the batch audit itself is not replay-stable. Task-level create/move keys are stable, but the batch audit should either accept an idempotency key or document that only task writes are idempotent.Recap actor filtering needs a high-volume regression test.
The current path correctly attributes after audit matching, but actor-filtered card activity is overfetch-based (
100before post-filter). Add a test with >100 unrelated activities so “co dziś zrobiła Iskra?” does not miss exact matches on busy boards.Machine identity CLI needs one more guard before production use.
Dry-run default is good. Before real prod issuance/rotation, add either a typed confirmation (
--confirm-slug) or explicit production guard, plus a small dry-run functional test.Deploy/rollback note must call out enum migration order.
Relation activity enum values must exist before relation activity writes. Add “migration first, then API/MCP” and note that Postgres enum additions are not trivially reversible.
Notes
projection:write,projection:override_warnings,KAN_PROJECTION_APPLY_ENABLED=false, exactactivityPublicId, redacted audit defaults, and/live//readyare the right shape.Codex follow-up fixes for 3+3 blockers
Pushed commit
686fa28to this draft PR.Addressed:
get_recent_activity.summary.movesnow separates canonical exact agent moves from low-confidence historical matches:agent/agentExact: exactactivityPublicIdlineage onlyagentLowConfidence: time-window fallback onlyactor: Iskrais less likely to miss exact matches on busy boards.idempotencyKey, defaults toleviathan:<projectionId>:apply, replays batch audit results, and stores structuredwarningCodes/warningOverrideUsedin audit input/result.tokenPublicIdandsecretArtifactRef-style references survive default redaction while actual token/secret/password-like keys remain redacted.--executenow requires--confirm-slug <exact-slug>for create/rotate/pause/revoke.Verification:
pnpm --filter @kan/api test -- agent.test.ts=> 24 passedpnpm --filter @kan/mcp test -- health.test.ts=> 1 passedpnpm --filter @kan/api typecheck=> passedpnpm --filter @kan/mcp typecheck=> passedpnpm --filter @kan/api exec eslint src/routers/agent.ts src/routers/agent.test.ts=> passednode --check scripts/kan-machine-identity-admin.mjs=> passedKnown repo-level lint note:
pnpm --filter @kan/api lintstill fails on pre-existing repo issues outside this patch, including integration-tests not included in tsconfig and unrelated router/utils lint findings.pnpm --filter @kan/mcp lintcurrently fails because ESLint 9 cannot find an eslint.config file for that package. Targeted typecheck/test passed.Focused 3+3 rerun after fixes
Scope: delta
fa443e8..686fa28only, i.e. the follow-up commit that addressed comment #6120.Gate result: OK for Piotr owner review, still no auto-merge.
Deterministic checks
diff_size, 577 changed lines >= 500pnpm --filter @kan/api test -- agent.test.ts=> 24 passedpnpm --filter @kan/mcp test -- health.test.ts=> 1 passedpnpm --filter @kan/api typecheck=> passedpnpm --filter @kan/mcp typecheck=> passedpnpm --filter @kan/api exec eslint src/routers/agent.ts src/routers/agent.test.ts=> passednode --check scripts/kan-machine-identity-admin.mjs=> passedReviewer verdicts
Blocker closure assessment
Residual risks, not blockers
leviathan:<projectionId>:apply; callers should use a new projectionId or explicit key when projection content changes.Recommendation
Keep PR #61 draft until Piotr reviews it, but from the focused 3+3 perspective the previous blockers are addressed. Next gate is Piotr owner review, not more Codex patching unless Piotr wants another round.
WIP: fix: harden kan-ductor agent safety gatesto fix: harden kan-ductor agent safety gates