Funcionalidade nucleo v3 - BrunodosSantosVaz/big-bang GitHub Wiki
Funcionalidade BB-F-050 · requisito RF-BB-050 · versão documentada 3.0.0 · código bff42ded9b4d83b4327f4064cc352f49c7659dfa.
Reunir as regras de controle da v3 em módulos puros e testados: quais transições do quadro único são permitidas e com que evidência (states), quem aprova cada portão em cada modo e qual o risco mínimo de uma mudança (policy), como cada ação deixa um recibo auditável (receipts) e como garantir exclusão real sobre um recurso (locks). ADR-0023 e ADR-0025.
Controlador da esteira v3, comandos bb claim/unclaim/renew/move/reject e os workflows que registram testes, revisões, QA e publicação; IAs e humanos usam o mesmo protocolo.
Os chamadores reúnem os fatos no GitHub (labels, sub-issues, PR, candidata, decisões) e passam para as regras; as travas precisam de token com permissão de escrever refs no repositório.
states.problems(tipo, atual, alvo, fatos) devolve por que uma transição não é permitida (lista vazia libera); policy.approver(modo, portão, risco, contrato) devolve owner, agent ou blocked; receipts.render/parse grava e lê recibos idempotentes por event_id; locks.Locks adquire, renova, retoma e libera travas em refs/bigbang/locks/ com geração como token de cerca. GitHub.pulls pagina a listagem uma vez e normaliza os campos presentes em cada resposta em memória, sem fazer uma consulta individual para cada PR.
Rejected exige motivo da família reason e retorno permitido pela etapa de origem; Cancelled exige motivo; impedimentos bloqueiam avanços; o rótulo risk:* só eleva o risco calculado pelos caminhos; recibos só valem da conta confiável e com campos obrigatórios; uma ref que não contém trava do Big Bang nunca é tratada como trava. Liberar uma trava grava uma lápide e nunca apaga a ref: uma liberação atrasada não remove a trava de outra sessão e a geração só cresce; trava vencida só é retomada por ordem do dono (--force-claim, com a frase dele) e uma sessão vencida não renova. Pessoas e agentes nunca compartilham o dono de uma trava.
Aquisição concorrente tem um vencedor (criação de ref existente devolve 422); retomada de trava vencida e renovação usam atualização fast-forward, que também devolve 422 se alguém mudou a ref; sessão substituída recebe LockLost e não pode concluir trabalho; modo, portão ou risco desconhecido cai no caso mais restrito. Lápides de trava nunca são apagadas (apagá-las reabriria a corrida e reiniciaria a geração); a capacidade e as posses vencidas leem só as travas das issues abertas.
As regras não concedem permissão: o modo autônomo só aprova dentro de um contrato autonomy.toml válido e nunca amplia o próprio alcance; só o controlador escreve as refs de trava. Portões de planejamento usam o risco declarado pelas áreas (médio por padrão); portões de QA e publicação usam os caminhos alterados e, sem eles, falham para alto. AGENTS.md/CLAUDE.md são risco alto e .bigbang/** crítico.
Decisões reproduzíveis e auditáveis para o controlador do quadro único, posse com exclusão real e base para reaproveitar evidência de testes do mesmo conteúdo sem repetir a suíte por hábito.
Os símbolos abaixo compõem o inventário real do módulo, incluindo auxiliares internos; não representam APIs públicas independentes.
| Símbolo | Linha |
|---|---|
kind |
45 |
_has |
51 |
targets |
56 |
_returns |
68 |
problems |
72 |
_rejection_problems |
103 |
_preconditions |
117 |
_need |
128 |
_done_subissues |
132 |
_flag_decided |
137 |
| Símbolo | Linha |
|---|---|
mode |
32 |
_rank |
41 |
approver |
45 |
_matches |
62 |
risk_floor |
68 |
_area_risk |
84 |
planning_risk |
89 |
delivery_risk |
94 |
effective_risk |
104 |
limits |
110 |
snapshot |
127 |
suite_on_promotion |
133 |
in_window |
141 |
contract_problems |
151 |
strings |
160 |
| Símbolo | Linha |
|---|---|
problems |
24 |
render |
34 |
parse |
54 |
find |
71 |
reuse_problems |
76 |
| Símbolo | Linha |
|---|---|
LockHeld |
20 |
LockLost |
28 |
_iso |
33 |
encode |
37 |
decode |
41 |
expired |
53 |
gh_api |
57 |
Locks |
81 |
__init__ |
21 |
_path |
85 |
_call |
88 |
_check |
96 |
_commit |
100 |
_head |
105 |
current |
116 |
_record |
122 |
acquire |
126 |
take_over |
143 |
renew |
159 |
release |
173 |
all |
185 |
| Símbolo | Linha |
|---|---|
is_v3 |
21 |
_now |
30 |
_iso |
34 |
_label |
38 |
_owner |
42 |
_check_name |
47 |
_open_issue |
57 |
_blockers |
64 |
_held_by |
71 |
_record |
81 |
claim |
85 |
_project |
109 |
renew |
120 |
unclaim |
127 |
force |
137 |
stale |
162 |
| Símbolo | Linha |
|---|---|
_labels |
14 |
normalize_issue |
18 |
_milestone |
26 |
_normalize_pull |
32 |
graphql |
39 |
GitHub |
57 |
__init__ |
58 |
call |
62 |
paginate |
69 |
repository_info |
82 |
user |
86 |
branch_rules |
90 |
ruleset |
93 |
environment |
97 |
environment_branch_policies |
101 |
issue |
107 |
issues |
111 |
create_issue |
115 |
update_issue |
119 |
add_labels |
122 |
remove_label |
126 |
ensure_label |
129 |
comments |
134 |
comment |
137 |
sub_issues |
143 |
parent |
146 |
add_sub_issue |
150 |
blocked_by |
154 |
add_blocked_by |
157 |
branches |
163 |
branch_sha |
167 |
create_branch |
171 |
pull |
177 |
merge_pull |
183 |
pull_files |
192 |
add_pr_labels |
195 |
check_runs |
198 |
compare_messages |
202 |
tags |
206 |
ensure_milestone |
210 |
milestone_number |
217 |
close_milestone |
223 |
milestone_issues |
226 |
pulls |
230 |
create_pull |
235 |
merge_branches |
245 |
ahead_by |
251 |
delete_ref |
255 |
all_branches |
258 |
locks |
262 |
.bigbang/tests/test_core_v3.py:test_fifteen_states_and_types.bigbang/tests/test_core_v3.py:test_kind_from_labels_in_both_dialects.bigbang/tests/test_core_v3.py:test_unknown_or_wrong_type_state.bigbang/tests/test_core_v3.py:test_epic_planning_route.bigbang/tests/test_core_v3.py:test_legacy_decision_labels_count.bigbang/tests/test_core_v3.py:test_selection_and_plan.bigbang/tests/test_core_v3.py:test_delivery_routes.bigbang/tests/test_core_v3.py:test_qa_and_release.bigbang/tests/test_core_v3.py:test_task_route.bigbang/tests/test_core_v3.py:test_bug_route.bigbang/tests/test_core_v3.py:test_bug_without_qa_but_with_publication_goes_to_releasing.bigbang/tests/test_core_v3.py:test_leaving_rejected_respects_impediments.bigbang/tests/test_core_v3.py:test_impediments_block_forward_but_not_reject_or_cancel.bigbang/tests/test_core_v3.py:test_rejection_needs_reason_and_allowed_return.bigbang/tests/test_core_v3.py:test_leaving_rejected_only_to_the_recorded_return.bigbang/tests/test_core_v3.py:test_terminal_states.bigbang/tests/test_core_v3.py:test_allowed_targets.bigbang/tests/test_core_v3.py:test_modes.bigbang/tests/test_core_v3.py:test_normal_owner_decides_every_gate.bigbang/tests/test_core_v3.py:test_flash_delegates_common_work_but_not_critical_or_selection.bigbang/tests/test_core_v3.py:test_autonomous_needs_a_contract_and_never_widens_it.bigbang/tests/test_core_v3.py:test_risk_floor_cannot_be_lowered.bigbang/tests/test_core_v3.py:test_contract_validation.bigbang/tests/test_core_v3.py:test_snapshot_is_canonical.bigbang/tests/test_core_v3.py:test_limits.bigbang/tests/test_core_v3.py:test_promotion_reuses_valid_evidence.bigbang/tests/test_core_v3.py:test_round_trip_and_comment_safety.bigbang/tests/test_core_v3.py:test_only_trusted_authors.bigbang/tests/test_core_v3.py:test_malformed_and_incomplete_are_ignored.bigbang/tests/test_core_v3.py:test_transition_without_a_known_sha.bigbang/tests/test_core_v3.py:test_required_fields_per_kind.bigbang/tests/test_core_v3.py:test_idempotency.bigbang/tests/test_core_v3.py:test_test_receipt_reuse.bigbang/tests/test_core_v3.py:test_resource_names.bigbang/tests/test_core_v3.py:test_one_winner_and_the_loser_learns_the_holder.bigbang/tests/test_core_v3.py:test_expired_lock_is_taken_over_only_on_request.bigbang/tests/test_core_v3.py:test_take_over_needs_the_same_mark_for_an_expired_lock.bigbang/tests/test_core_v3.py:test_listing_only_the_requested_locks.bigbang/tests/test_core_v3.py:test_take_over_refuses_a_live_lock.bigbang/tests/test_core_v3.py:test_release_keeps_a_tombstone_so_a_late_release_cannot_delete_another_lock.bigbang/tests/test_core_v3.py:test_expired_lock_cannot_be_renewed.bigbang/tests/test_core_v3.py:test_unexpected_422_is_an_error_not_a_loop.bigbang/tests/test_core_v3.py:test_lock_commits_use_the_empty_tree_constant.bigbang/tests/test_core_v3.py:test_concurrent_takeover_has_one_winner.bigbang/tests/test_core_v3.py:test_renew_only_by_the_holder_and_generation.bigbang/tests/test_core_v3.py:test_expired_session_cannot_renew_after_takeover.bigbang/tests/test_core_v3.py:test_release_only_by_the_holder.bigbang/tests/test_core_v3.py:test_listing_and_expiry.bigbang/tests/test_core_v3.py:test_foreign_ref_content_is_never_trusted_as_a_lock.bigbang/tests/test_core_v3.py:test_status_and_body.bigbang/tests/test_core_v3.py:test_no_http_status_is_an_error.bigbang/tests/test_claims_v3.py:test_agent_claim_locks_labels_and_records.bigbang/tests/test_claims_v3.py:test_person_claim_uses_the_login.bigbang/tests/test_claims_v3.py:test_unknown_agent_and_closed_or_pr_issues_are_refused.bigbang/tests/test_claims_v3.py:test_blocked_task_is_refused_until_the_blocker_closes.bigbang/tests/test_claims_v3.py:test_second_claim_on_the_same_issue_loses_with_the_holder_named.bigbang/tests/test_claims_v3.py:test_capacity_per_session.bigbang/tests/test_claims_v3.py:test_capacity_counts_the_locks_even_without_the_projection_label.bigbang/tests/test_claims_v3.py:test_epic_stages_can_be_claimed.bigbang/tests/test_claims_v3.py:test_renew_extends_the_lease.bigbang/tests/test_claims_v3.py:test_unclaim_releases_lock_and_label.bigbang/tests/test_claims_v3.py:test_expired_claim_of_another_needs_the_owner_order.bigbang/tests/test_claims_v3.py:test_people_and_agents_never_collide.bigbang/tests/test_claims_v3.py:test_expired_session_cannot_renew.bigbang/tests/test_claims_v3.py:test_failed_force_leaves_no_owner_order_comment.bigbang/tests/test_claims_v3.py:test_live_lock_cannot_be_forced.bigbang/tests/test_claims_v3.py:test_expired_lock_is_forced_with_the_owner_order_and_fences_the_old_session.bigbang/tests/test_claims_v3.py:test_stale_report_lists_expired_claims.bigbang/tests/test_claims_v3.py:test_v3_when_the_workflow_or_labels_are_v3