pomaster 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -10
- package/catalog/archetypes/archetype.frontend.error_taxonomy.json +13 -5
- package/catalog/archetypes/archetype.frontend.feature_oriented.json +1 -1
- package/catalog/archetypes/archetype.state.async_command.json +4 -4
- package/catalog/catalog-lock.draft.json +1120 -104
- package/catalog/gates/gate.be.api.contract_checks.json +2 -1
- package/catalog/gates/gate.be.chg.contract_change_checks.json +2 -1
- package/catalog/gates/gate.chg.prechange_checks.json +2 -1
- package/catalog/gates/gate.web.api.request_checks.json +2 -1
- package/catalog/gates/gate.web.grid.checks.json +2 -1
- package/catalog/knowledge/knowledge.api.example_stable_error_code.json +2 -1
- package/catalog/knowledge/knowledge.chg.example_compat_window.json +2 -1
- package/catalog/knowledge/knowledge.chg.example_prop_migration.json +2 -1
- package/catalog/knowledge/knowledge.fp.api.field_drift_no_contract.json +2 -1
- package/catalog/knowledge/knowledge.fp.api.per_page_http_client.json +2 -1
- package/catalog/knowledge/knowledge.fp.be.contract_drift.json +2 -1
- package/catalog/knowledge/knowledge.fp.chg.page_local_padding.json +2 -1
- package/catalog/knowledge/knowledge.fp.grid.global_td_width.json +2 -1
- package/catalog/knowledge/knowledge.web.api.example_get_entity_list.json +2 -1
- package/catalog/knowledge/knowledge.web.grid.example_column_preset.json +2 -1
- package/catalog/policies/authority.be.api_contract_ownership.json +2 -1
- package/catalog/policies/authority.be.contract_ownership.json +2 -1
- package/catalog/policies/authority.chg.change_owners.json +2 -1
- package/catalog/policies/authority.web.api.request_owners.json +2 -1
- package/catalog/policies/authority.web.grid.ownership.json +2 -1
- package/catalog/policies/policy.ai.change_plan_first.json +91 -0
- package/catalog/policies/policy.ai.fact_inference_separation.json +91 -0
- package/catalog/policies/policy.ai.read_search_verify_before_write.json +92 -0
- package/catalog/policies/policy.ai.rule_relaxation_approval.json +91 -0
- package/catalog/policies/policy.api.backward_compat_defaults.json +2 -1
- package/catalog/policies/policy.api.contract_impl_consistency.json +2 -1
- package/catalog/policies/policy.api.no_informal_contract.json +2 -1
- package/catalog/policies/policy.arch.adr_immutable_history.json +91 -0
- package/catalog/policies/policy.arch.decision_tradeoff_record.json +2 -1
- package/catalog/policies/policy.arch.no_convenience_over_boundary.json +93 -0
- package/catalog/policies/policy.arch.prefer_verifiable_option.json +92 -0
- package/catalog/policies/policy.authz.no_gating_proxy_trust.json +99 -0
- package/catalog/policies/policy.authz.permission_scope_expansion_gate.json +99 -0
- package/catalog/policies/policy.authz.server_five_factor_verification.json +101 -0
- package/catalog/policies/policy.be.conc.prefer_db_constraints.json +97 -0
- package/catalog/policies/policy.be.db.expand_migrate_contract.json +97 -0
- package/catalog/policies/policy.be.idem.key_payload_conflict.json +97 -0
- package/catalog/policies/policy.be.model.single_boundary_conversion.json +97 -0
- package/catalog/policies/policy.be.sql.index_for_known_queries.json +97 -0
- package/catalog/policies/policy.be.state.single_rule_source.json +97 -0
- package/catalog/policies/policy.be.txn.short_locks_compensation.json +96 -0
- package/catalog/policies/policy.bound.search_first_entry_only.json +91 -0
- package/catalog/policies/policy.boundary.validate_in_encode_out.json +92 -0
- package/catalog/policies/policy.cache.failure_mode_guards.json +93 -0
- package/catalog/policies/policy.cache.lifecycle_definition.json +2 -1
- package/catalog/policies/policy.cache.schema_versioning.json +91 -0
- package/catalog/policies/policy.cfg.config_attribute_completeness.json +95 -0
- package/catalog/policies/policy.cfg.key_rename_dual_read.json +92 -0
- package/catalog/policies/policy.cfg.no_secret_dispersal.json +90 -0
- package/catalog/policies/policy.cfg.production_safe_defaults.json +92 -0
- package/catalog/policies/policy.cfg.schema_backed_config.json +92 -0
- package/catalog/policies/policy.chg.affect_templates.json +2 -1
- package/catalog/policies/policy.chg.breaking_versioning.json +2 -1
- package/catalog/policies/policy.chg.compat_migration_rollback.json +2 -1
- package/catalog/policies/policy.chg.deprecate_before_delete.json +2 -1
- package/catalog/policies/policy.chg.fix_at_root_cause_level.json +2 -1
- package/catalog/policies/policy.chg.no_unrelated_changes.json +91 -0
- package/catalog/policies/policy.chg.observable_evolution.json +2 -1
- package/catalog/policies/policy.chg.prechange_consumer_scan.json +2 -1
- package/catalog/policies/policy.chg.staged_rollout.json +2 -1
- package/catalog/policies/policy.chg.sync_contract_docs_tests.json +2 -1
- package/catalog/policies/policy.conflict.priority_ladder.json +2 -1
- package/catalog/policies/policy.contract.no_invented_facts.json +93 -0
- package/catalog/policies/policy.dep.admission_six_dimension_check.json +2 -1
- package/catalog/policies/policy.dep.build_path_supply_chain.json +93 -0
- package/catalog/policies/policy.dep.change_surface_review.json +2 -1
- package/catalog/policies/policy.dep.introduction_review.json +2 -1
- package/catalog/policies/policy.dep.no_untrusted_source_no_lock_bypass.json +92 -0
- package/catalog/policies/policy.dep.time_boxed_urgent_exception.json +91 -0
- package/catalog/policies/policy.deploy.no_dev_env_as_production_fact.json +91 -0
- package/catalog/policies/policy.deploy.operational_capabilities.json +93 -0
- package/catalog/policies/policy.deploy.runtime_fact_record.json +97 -0
- package/catalog/policies/policy.derived.single_implementation.json +2 -1
- package/catalog/policies/policy.err.failure_five_part_mapping.json +101 -0
- package/catalog/policies/policy.err.no_internal_detail_exposure.json +97 -0
- package/catalog/policies/policy.err.published_code_immutable.json +98 -0
- package/catalog/policies/policy.evid.acceptance_binds_verifiable_evidence.json +92 -0
- package/catalog/policies/policy.evid.no_silent_gate_removal.json +90 -0
- package/catalog/policies/policy.evid.no_unverifiable_pass.json +92 -0
- package/catalog/policies/policy.flag.cleanup_after_full_rollout.json +94 -0
- package/catalog/policies/policy.flag.consistent_off_state.json +92 -0
- package/catalog/policies/policy.flag.kill_switch.json +91 -0
- package/catalog/policies/policy.flag.lifecycle_metadata.json +93 -0
- package/catalog/policies/policy.flag.not_a_permission.json +92 -0
- package/catalog/policies/policy.gate.p0_non_bypassable.json +92 -0
- package/catalog/policies/policy.gate.risk_factors_confirmed.json +93 -0
- package/catalog/policies/policy.guard.no_check_weakening.json +92 -0
- package/catalog/policies/policy.integration.call_definition_minimum.json +95 -0
- package/catalog/policies/policy.integration.fault_containment.json +94 -0
- package/catalog/policies/policy.job.lifecycle_definition.json +96 -0
- package/catalog/policies/policy.job.no_unmanaged_execution.json +92 -0
- package/catalog/policies/policy.job.operational_features.json +93 -0
- package/catalog/policies/policy.obs.actionable_signals.json +93 -0
- package/catalog/policies/policy.obs.alert_with_owner.json +91 -0
- package/catalog/policies/policy.obs.context_field_baseline.json +91 -0
- package/catalog/policies/policy.obs.correlation_context_minimum.json +2 -1
- package/catalog/policies/policy.obs.no_sensitive_or_unbounded_logging.json +92 -0
- package/catalog/policies/policy.obs.no_sensitive_raw_values.json +93 -0
- package/catalog/policies/policy.obs.rum_dimension_whitelist.json +2 -1
- package/catalog/policies/policy.obs.signal_change_impact.json +91 -0
- package/catalog/policies/policy.obs.source_map_access_control.json +92 -0
- package/catalog/policies/policy.obs.telemetry_lifecycle_declared.json +93 -0
- package/catalog/policies/policy.obs.trace_correlation.json +91 -0
- package/catalog/policies/policy.perf.budget_change_retest.json +91 -0
- package/catalog/policies/policy.perf.evidence_binding.json +95 -0
- package/catalog/policies/policy.perf.observation_dimensions.json +94 -0
- package/catalog/policies/policy.proc.checklist_change_policy.json +91 -0
- package/catalog/policies/policy.proc.pre_code_declaration.json +2 -1
- package/catalog/policies/policy.proc.scope_drift_reclassify.json +91 -0
- package/catalog/policies/policy.prv.processing_scope_re_review.json +97 -0
- package/catalog/policies/policy.prv.sensitive_data_six_facts.json +102 -0
- package/catalog/policies/policy.registry.human_fields_validated_decorrelated.json +93 -0
- package/catalog/policies/policy.rel.no_irreversible_unmonitored_full_release.json +91 -0
- package/catalog/policies/policy.rel.observability_before_ship.json +91 -0
- package/catalog/policies/policy.rel.pre_release_confirmation.json +2 -1
- package/catalog/policies/policy.rel.process_change_needs_drill_audit.json +91 -0
- package/catalog/policies/policy.rel.traceable_build.json +93 -0
- package/catalog/policies/policy.role.domain_decision_authority.json +2 -1
- package/catalog/policies/policy.role.human_signs_for_ai.json +93 -0
- package/catalog/policies/policy.sec.authn_policy_unified.json +91 -0
- package/catalog/policies/policy.sec.no_client_side_trust.json +92 -0
- package/catalog/policies/policy.sec.no_longterm_security_disable.json +91 -0
- package/catalog/policies/policy.sec.no_script_readable_credentials.json +91 -0
- package/catalog/policies/policy.sec.no_secrets_in_client_surface.json +91 -0
- package/catalog/policies/policy.sec.relaxation_approval.json +92 -0
- package/catalog/policies/policy.sec.security_relaxation_gate.json +92 -0
- package/catalog/policies/policy.sec.third_party_execution_register.json +2 -1
- package/catalog/policies/policy.sec.trust_boundary_enforcement.json +93 -0
- package/catalog/policies/policy.sec.upload_download_server_recheck.json +91 -0
- package/catalog/policies/policy.sec.url_source_allowlist.json +91 -0
- package/catalog/policies/policy.spec.admission_criteria.json +2 -1
- package/catalog/policies/policy.spec.derived_view_regeneration.json +2 -1
- package/catalog/policies/policy.spec.draft_not_baseline.json +2 -1
- package/catalog/policies/policy.spec.family_conflict_precedence.json +93 -0
- package/catalog/policies/policy.spec.file_structure_contract.json +2 -1
- package/catalog/policies/policy.spec.freeze_before_use.json +93 -0
- package/catalog/policies/policy.spec.metadata_required.json +2 -1
- package/catalog/policies/policy.spec.post_dev_backfill_classify.json +2 -1
- package/catalog/policies/policy.spec.primary_source_basis.json +93 -0
- package/catalog/policies/policy.spec.procedural_record_not_surrogate.json +2 -1
- package/catalog/policies/policy.spec.semantic_identity.json +2 -1
- package/catalog/policies/policy.spec.unresolved_ledger_gate.json +2 -1
- package/catalog/policies/policy.stack.derived_store_not_authority.json +93 -0
- package/catalog/policies/policy.stack.dual_web_stack_boundary.json +93 -0
- package/catalog/policies/policy.stack.entry_chain_recorded.json +93 -0
- package/catalog/policies/policy.stack.entry_limits_aligned.json +94 -0
- package/catalog/policies/policy.stack.local_form_not_prod_fact.json +93 -0
- package/catalog/policies/policy.stack.multi_datastore_ownership.json +93 -0
- package/catalog/policies/policy.stack.no_implicit_selection.json +2 -1
- package/catalog/policies/policy.stack.persistence_coexistence_scope.json +93 -0
- package/catalog/policies/policy.stack.toolchain_versions_pinned.json +95 -0
- package/catalog/policies/policy.stack.upgrade_compat_verified.json +93 -0
- package/catalog/policies/policy.struct.module_entry_dependency_declared.json +92 -0
- package/catalog/policies/policy.struct.no_unexplained_top_level_dir.json +91 -0
- package/catalog/policies/policy.struct.reuse_proven_structure.json +91 -0
- package/catalog/policies/policy.test.control_nondeterminism_keep_diagnosis.json +91 -0
- package/catalog/policies/policy.test.isolation_and_cleanup.json +93 -0
- package/catalog/policies/policy.test.no_synthetic_stability.json +92 -0
- package/catalog/policies/policy.test.pyramid_and_ci_matrix.json +92 -0
- package/catalog/policies/policy.test.removal_justification.json +91 -0
- package/catalog/policies/policy.test.removal_needs_substitute_evidence.json +91 -0
- package/catalog/policies/policy.test.risk_driven_plan.json +92 -0
- package/catalog/policies/policy.test.stable_observable_assertions.json +92 -0
- package/catalog/policies/policy.tool.discoverable_toolchain.json +92 -0
- package/catalog/policies/policy.tool.no_hand_edit_generated_no_ci_drift.json +91 -0
- package/catalog/policies/policy.tool.no_vendored_body_edits.json +94 -0
- package/catalog/policies/policy.tool.scoped_scan_boundary.json +2 -1
- package/catalog/policies/policy.tool.upgrade_verify_lock_rollback.json +92 -0
- package/catalog/policies/policy.web.api.auth_app_client_split.json +2 -1
- package/catalog/policies/policy.web.api.client_change_impact.json +2 -1
- package/catalog/policies/policy.web.api.domain_api_only.json +2 -1
- package/catalog/policies/policy.web.api.error_normalization.json +2 -1
- package/catalog/policies/policy.web.api.generated_client.json +2 -1
- package/catalog/policies/policy.web.api.late_result_guard.json +2 -1
- package/catalog/policies/policy.web.api.mutation_idempotency.json +2 -1
- package/catalog/policies/policy.web.api.no_network_optimism.json +2 -1
- package/catalog/policies/policy.web.api.query_cancel_stale_drop.json +2 -1
- package/catalog/policies/policy.web.api.request_infrastructure.json +2 -1
- package/catalog/policies/policy.web.api.retry_discipline.json +2 -1
- package/catalog/policies/policy.web.api.session_recovery_split.json +2 -1
- package/catalog/policies/policy.web.api.single_http_client.json +2 -1
- package/catalog/policies/policy.web.api.single_loading_source.json +2 -1
- package/catalog/policies/policy.web.api.transport_vs_business.json +2 -1
- package/catalog/policies/policy.web.api.trusted_endpoint_source.json +2 -1
- package/catalog/policies/policy.web.api.typed_domain_naming.json +2 -1
- package/catalog/policies/policy.web.arch.layer_isolation.json +2 -1
- package/catalog/policies/policy.web.arch.naming_conventions.json +2 -1
- package/catalog/policies/policy.web.arch.public_api_barrel.json +2 -1
- package/catalog/policies/policy.web.chg.controlled_change_triggers.json +2 -1
- package/catalog/policies/policy.web.comp.no_trivial_or_god_component.json +91 -0
- package/catalog/policies/policy.web.comp.public_contract_completeness.json +93 -0
- package/catalog/policies/policy.web.copy.action_object_clarity.json +92 -0
- package/catalog/policies/policy.web.copy.enumerable_placement.json +91 -0
- package/catalog/policies/policy.web.copy.error_next_step.json +92 -0
- package/catalog/policies/policy.web.copy.suppression_ledger_discipline.json +2 -1
- package/catalog/policies/policy.web.grid.column_schema_fields.json +2 -1
- package/catalog/policies/policy.web.grid.config_isolation.json +2 -1
- package/catalog/policies/policy.web.grid.freeze_key_columns.json +2 -1
- package/catalog/policies/policy.web.grid.interaction_registry.json +2 -1
- package/catalog/policies/policy.web.grid.keyboard_clipboard.json +2 -1
- package/catalog/policies/policy.web.grid.schema_driven_shell.json +2 -1
- package/catalog/policies/policy.web.grid.schema_versioning.json +2 -1
- package/catalog/policies/policy.web.grid.server_ops_virtualization.json +2 -1
- package/catalog/policies/policy.web.grid.shell_change_matrix.json +2 -1
- package/catalog/policies/policy.web.grid.width_fix_ladder.json +2 -1
- package/catalog/policies/policy.web.handoff.state_matrix_full.json +94 -0
- package/catalog/policies/policy.web.i18n.copy_key_discipline.json +92 -0
- package/catalog/policies/policy.web.i18n.raw_value_for_compute.json +91 -0
- package/catalog/policies/policy.web.page.region_consistency.json +93 -0
- package/catalog/policies/policy.web.perf.budget_skeleton.json +2 -1
- package/catalog/policies/policy.web.style.ownership_matrix.json +2 -1
- package/catalog/policies/policy.web.track.attempt_result_correlation.json +91 -0
- package/catalog/policies/policy.web.track.consent_lifecycle.json +2 -1
- package/catalog/policies/policy.web.track.no_synthetic_actions.json +92 -0
- package/catalog/policies/policy.web.track.privacy_default_deny.json +2 -1
- package/catalog/policies/policy.web.track.stable_event_keys.json +2 -1
- package/catalog/policies/policy.web.track.typed_client_validation.json +91 -0
- package/catalog/policies/policy.web.uiux.provider_evidence_not_business_truth.json +2 -1
- package/catalog/policies/policy.wf.no_planned_as_verified.json +91 -0
- package/catalog/policies/policy.wf.task_facts_preconfirm.json +94 -0
- package/catalog/policies/profile.baseline.java_enterprise_default.json +96 -0
- package/catalog/sensors/sensor.browser.deterministic.json +2 -1
- package/catalog/sensors/sensor.browser.interactive.json +2 -1
- package/catalog/sensors/sensor.build.static.json +2 -1
- package/catalog/sensors/sensor.contract.conformance.json +2 -1
- package/catalog/sensors/sensor.performance.budget.json +2 -1
- package/catalog/sensors/sensor.production.metric.json +2 -1
- package/catalog/tools/seed_b6b_frontend.py +1424 -0
- package/catalog/tools/seed_b6c_backend.py +1495 -0
- package/catalog/tools/seed_b6d_baseline.py +620 -0
- package/catalog/tools/seed_b6e_evidence.py +1305 -0
- package/catalog/tools/seed_d3_review.py +1105 -0
- package/catalog/tools/seed_v06_batch2_materials.py +27 -18
- package/dist/bin.js +23026 -16635
- package/package.json +2 -1
- package/seeds/baseline/backend/api-contract.md +26 -0
- package/seeds/baseline/backend/architecture.md +31 -0
- package/seeds/baseline/backend/data-access.md +31 -0
- package/seeds/baseline/backend/directory-structure.md +11 -0
- package/seeds/baseline/backend/integration-runtime.md +21 -0
- package/seeds/baseline/backend/quality.md +31 -0
- package/seeds/baseline/backend/stack.yaml +13 -0
- package/seeds/baseline/backend/transaction-concurrency.md +26 -0
- package/seeds/baseline/data/lineage.md +11 -0
- package/seeds/baseline/data/migration.md +11 -0
- package/seeds/baseline/data/model.md +31 -0
- package/seeds/baseline/data/precision-units.md +31 -0
- package/seeds/baseline/data/quality.md +31 -0
- package/seeds/baseline/frontend/api-and-error.md +21 -0
- package/seeds/baseline/frontend/architecture.md +26 -0
- package/seeds/baseline/frontend/design-system.md +21 -0
- package/seeds/baseline/frontend/directory-structure.md +16 -0
- package/seeds/baseline/frontend/quality.md +26 -0
- package/seeds/baseline/frontend/stack.yaml +17 -0
- package/seeds/baseline/frontend/state-and-data.md +26 -0
- package/seeds/baseline/manifest.yaml +32 -0
- package/seeds/baseline/platform/delivery.md +36 -0
- package/seeds/baseline/platform/environment.md +11 -0
- package/seeds/baseline/platform/observability.md +31 -0
- package/seeds/baseline/platform/security.md +26 -0
- package/seeds/manifest.json +2006 -0
- package/seeds/specs/evidence/accessibility.md +89 -0
- package/seeds/specs/evidence/architecture.md +89 -0
- package/seeds/specs/evidence/browser-e2e.md +91 -0
- package/seeds/specs/evidence/build.md +91 -0
- package/seeds/specs/evidence/business-acceptance.md +89 -0
- package/seeds/specs/evidence/complexity-crap.md +97 -0
- package/seeds/specs/evidence/contract.md +89 -0
- package/seeds/specs/evidence/coverage.md +91 -0
- package/seeds/specs/evidence/data-migration.md +91 -0
- package/seeds/specs/evidence/dead-code-duplicate.md +89 -0
- package/seeds/specs/evidence/dependency-supply-chain.md +89 -0
- package/seeds/specs/evidence/index.md +55 -0
- package/seeds/specs/evidence/mutation.md +89 -0
- package/seeds/specs/evidence/performance.md +89 -0
- package/seeds/specs/evidence/release.md +91 -0
- package/seeds/specs/evidence/runtime-observability.md +91 -0
- package/seeds/specs/evidence/security.md +89 -0
- package/seeds/specs/evidence/typecheck-lint.md +91 -0
- package/seeds/specs/evidence/unit-component-integration.md +91 -0
- package/seeds/specs/evidence/visual-regression.md +89 -0
- package/seeds/specs/hard/backend/01-architecture-governance-protocol.md +68 -0
- package/seeds/specs/hard/backend/02-project-structure-governance-protocol.md +68 -0
- package/seeds/specs/hard/backend/03-directory-boundary-protocol.md +68 -0
- package/seeds/specs/hard/backend/04-layering-architecture-protocol.md +68 -0
- package/seeds/specs/hard/backend/05-task-workflow-protocol.md +68 -0
- package/seeds/specs/hard/backend/06-ai-generated-code-protocol.md +68 -0
- package/seeds/specs/hard/backend/07-evidence-acceptance-protocol.md +68 -0
- package/seeds/specs/hard/backend/08-contract-change-protocol.md +68 -0
- package/seeds/specs/hard/backend/09-role-responsibility-protocol.md +68 -0
- package/seeds/specs/hard/backend/10-security-protocol.md +68 -0
- package/seeds/specs/hard/backend/11-environment-configuration-protocol.md +67 -0
- package/seeds/specs/hard/backend/12-api-contract-protocol.md +68 -0
- package/seeds/specs/hard/backend/13-privacy-data-lifecycle-protocol.md +68 -0
- package/seeds/specs/hard/backend/14-business-rules-state-protocol.md +68 -0
- package/seeds/specs/hard/backend/15-data-model-protocol.md +68 -0
- package/seeds/specs/hard/backend/16-error-code-protocol.md +68 -0
- package/seeds/specs/hard/backend/17-permission-authorization-protocol.md +68 -0
- package/seeds/specs/hard/backend/18-database-schema-migration-protocol.md +68 -0
- package/seeds/specs/hard/backend/19-query-index-sql-protocol.md +68 -0
- package/seeds/specs/hard/backend/20-transaction-boundary-protocol.md +68 -0
- package/seeds/specs/hard/backend/21-concurrency-locking-protocol.md +68 -0
- package/seeds/specs/hard/backend/22-idempotency-protocol.md +68 -0
- package/seeds/specs/hard/backend/23-cache-redis-consistency-protocol.md +68 -0
- package/seeds/specs/hard/backend/24-external-integration-resilience-protocol.md +68 -0
- package/seeds/specs/hard/backend/25-async-job-scheduler-protocol.md +68 -0
- package/seeds/specs/hard/backend/26-engineering-tooling-protocol.md +68 -0
- package/seeds/specs/hard/backend/27-dependency-supply-chain-protocol.md +68 -0
- package/seeds/specs/hard/backend/28-testing-protocol.md +68 -0
- package/seeds/specs/hard/backend/29-observability-logging-tracing-protocol.md +68 -0
- package/seeds/specs/hard/backend/30-performance-capacity-protocol.md +68 -0
- package/seeds/specs/hard/backend/31-runtime-deployment-protocol.md +68 -0
- package/seeds/specs/hard/backend/32-release-versioning-rollback-protocol.md +68 -0
- package/seeds/specs/hard/backend/index.md +177 -0
- package/seeds/specs/hard/frontend/01-development-checklist-protocol.md +86 -0
- package/seeds/specs/hard/frontend/02-ai-generated-code-protocol.md +82 -0
- package/seeds/specs/hard/frontend/03-acceptance-gate-protocol.md +86 -0
- package/seeds/specs/hard/frontend/04-security-protocol.md +283 -0
- package/seeds/specs/hard/frontend/05-environment-configuration-protocol.md +80 -0
- package/seeds/specs/hard/frontend/06-change-governance-protocol.md +90 -0
- package/seeds/specs/hard/frontend/07-frontend-backend-communication-protocol.md +219 -0
- package/seeds/specs/hard/frontend/08-role-responsibility-protocol.md +80 -0
- package/seeds/specs/hard/frontend/09-module-boundary-protocol.md +81 -0
- package/seeds/specs/hard/frontend/10-engineering-tooling-protocol.md +89 -0
- package/seeds/specs/hard/frontend/11-dependency-package-management-protocol.md +87 -0
- package/seeds/specs/hard/frontend/12-business-rules-protocol.md +79 -0
- package/seeds/specs/hard/frontend/13-monetary-precision-protocol.md +81 -0
- package/seeds/specs/hard/frontend/14-data-model-protocol.md +85 -0
- package/seeds/specs/hard/frontend/15-request-api-protocol.md +87 -0
- package/seeds/specs/hard/frontend/16-error-handling-protocol.md +79 -0
- package/seeds/specs/hard/frontend/17-permission-protocol.md +79 -0
- package/seeds/specs/hard/frontend/18-state-management-protocol.md +88 -0
- package/seeds/specs/hard/frontend/19-cache-protocol.md +79 -0
- package/seeds/specs/hard/frontend/20-testing-protocol.md +88 -0
- package/seeds/specs/hard/frontend/21-design-system-protocol.md +79 -0
- package/seeds/specs/hard/frontend/22-theme-protocol.md +79 -0
- package/seeds/specs/hard/frontend/23-accessibility-protocol.md +189 -0
- package/seeds/specs/hard/frontend/24-component-protocol.md +80 -0
- package/seeds/specs/hard/frontend/25-page-structure-protocol.md +79 -0
- package/seeds/specs/hard/frontend/26-style-layout-protocol.md +80 -0
- package/seeds/specs/hard/frontend/27-rendering-state-protocol.md +81 -0
- package/seeds/specs/hard/frontend/28-form-protocol.md +88 -0
- package/seeds/specs/hard/frontend/29-routing-url-protocol.md +79 -0
- package/seeds/specs/hard/frontend/30-data-grid-protocol.md +83 -0
- package/seeds/specs/hard/frontend/31-performance-protocol.md +137 -0
- package/seeds/specs/hard/frontend/32-file-import-export-protocol.md +80 -0
- package/seeds/specs/hard/frontend/33-release-versioning-protocol.md +79 -0
- package/seeds/specs/hard/frontend/34-monitoring-logging-protocol.md +128 -0
- package/seeds/specs/hard/frontend/35-mock-protocol.md +97 -0
- package/seeds/specs/hard/frontend/36-feature-flag-protocol.md +79 -0
- package/seeds/specs/hard/frontend/37-browser-device-compatibility-protocol.md +83 -0
- package/seeds/specs/hard/frontend/38-internationalization-protocol.md +243 -0
- package/seeds/specs/hard/frontend/39-copywriting-protocol.md +79 -0
- package/seeds/specs/hard/frontend/40-analytics-protocol.md +98 -0
- package/seeds/specs/hard/frontend/41-design-handoff-protocol.md +80 -0
- package/seeds/specs/hard/frontend/42-browser-runtime-lifecycle-protocol.md +86 -0
- package/seeds/specs/hard/frontend/43-time-temporal-protocol.md +86 -0
- package/seeds/specs/hard/frontend/44-privacy-data-lifecycle-protocol.md +87 -0
- package/seeds/specs/hard/frontend/45-browser-storage-protocol.md +87 -0
- package/seeds/specs/hard/frontend/index.md +308 -0
- package/seeds/specs/hard/stacks/java/index.md +20 -0
- package/seeds/specs/hard/stacks/java/java-language-overlay.md +35 -0
- package/seeds/specs/hard/stacks/jpa/index.md +20 -0
- package/seeds/specs/hard/stacks/jpa/jpa-persistence-overlay.md +35 -0
- package/seeds/specs/hard/stacks/kubernetes-ingress/index.md +20 -0
- package/seeds/specs/hard/stacks/kubernetes-ingress/kubernetes-ingress-overlay.md +35 -0
- package/seeds/specs/hard/stacks/messaging/index.md +20 -0
- package/seeds/specs/hard/stacks/messaging/messaging-reliability-overlay.md +35 -0
- package/seeds/specs/hard/stacks/mybatis/index.md +20 -0
- package/seeds/specs/hard/stacks/mybatis/mybatis-persistence-overlay.md +35 -0
- package/seeds/specs/hard/stacks/mysql/index.md +20 -0
- package/seeds/specs/hard/stacks/mysql/mysql-database-overlay.md +35 -0
- package/seeds/specs/hard/stacks/nginx/index.md +20 -0
- package/seeds/specs/hard/stacks/nginx/nginx-proxy-overlay.md +35 -0
- package/seeds/specs/hard/stacks/postgresql/index.md +20 -0
- package/seeds/specs/hard/stacks/postgresql/postgresql-database-overlay.md +35 -0
- package/seeds/specs/hard/stacks/redis/index.md +20 -0
- package/seeds/specs/hard/stacks/redis/redis-cache-overlay.md +35 -0
- package/seeds/specs/hard/stacks/spring-batch/index.md +20 -0
- package/seeds/specs/hard/stacks/spring-batch/spring-batch-job-overlay.md +35 -0
- package/seeds/specs/hard/stacks/spring-boot/index.md +20 -0
- package/seeds/specs/hard/stacks/spring-boot/spring-boot-application-overlay.md +35 -0
- package/seeds/specs/hard/stacks/spring-mvc/index.md +20 -0
- package/seeds/specs/hard/stacks/spring-mvc/spring-mvc-web-overlay.md +35 -0
- package/seeds/specs/hard/stacks/spring-webflux/index.md +20 -0
- package/seeds/specs/hard/stacks/spring-webflux/spring-webflux-reactive-overlay.md +35 -0
- package/seeds/specs/hard/stacks/tomcat/index.md +20 -0
- package/seeds/specs/hard/stacks/tomcat/tomcat-runtime-overlay.md +35 -0
|
@@ -0,0 +1,1424 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""B6b FE 协议移植工具(B6b-I 前 23 份 + B6b-II 后半 24-45/index;播种资产 + provenance
|
|
3
|
+
pin + D5 精选 policies)。
|
|
4
|
+
|
|
5
|
+
输入(只读):
|
|
6
|
+
- pomaster/components/frontend-hard-spec/assets/universal/ vendor 播种源(46 文件分母)
|
|
7
|
+
- corpus/spec-knowledge/candidates/consolidated-pool.yaml SPEC-D 汇总池(卡分母=MASTer)
|
|
8
|
+
- corpus/spec-knowledge/candidates/{FE-G1..FE-G4}.yaml 候选组卡(raw statement)
|
|
9
|
+
|
|
10
|
+
输出:
|
|
11
|
+
- packages/cli/seeds/specs/hard/frontend/*.md 播种件(统一 frontmatter + vendor 正文
|
|
12
|
+
逐字节;index.md 为唯一授权词形适配点,见 INDEX_ADAPTATIONS)
|
|
13
|
+
- packages/cli/seeds/manifest.json 播种清单单源(逐文件 vendor sha256/bytes
|
|
14
|
+
pin;两批合并清单——B6b-I 条目按 vendor 字节确定性重算逐字节不变)
|
|
15
|
+
- catalog/policies/policy.*.json D5 精选(B6b-I 25 条 + B6b-II 25 条,
|
|
16
|
+
各批内 22 required + 3 advisory)
|
|
17
|
+
|
|
18
|
+
移植形态定案(ADR-lite,Owner 裁定 B5/D20 框架内):
|
|
19
|
+
- 移植 = 分解 + 形态改造,技术内容零语义重写:播种件正文 = vendor 正文逐字节
|
|
20
|
+
(工具构建两遍逐字节断言);frontmatter 增补(PRD §8.2 字段位——id 字段缺席,
|
|
21
|
+
no-governed-id 默认:播种 spec 文件是项目可编辑自由文件,治理绑定住 catalog
|
|
22
|
+
policy 面,Owner 未授权加 governed id 语义 → R6 词形裁定以 no-governed-id 回避);
|
|
23
|
+
- provenance pin(R1 漂移缓解,双分母如实标注):清单逐条 vendor sha256+bytes
|
|
24
|
+
(播种分母);FE 06/15/30(vendor↔MASTer 漂移文件,B6b-I 含 06/15、B6b-II 含
|
|
25
|
+
30)pin 由 spec-inventory pilot_verification 钉死值对账(全等断言——B6b-II 收紧,
|
|
26
|
+
去 64-bit 截断回退;测试侧同钉)——pin 对账通过 = 工具取材确为 vendor 字节;池卡
|
|
27
|
+
行号锚与 LCS 审计按 MASTer 消费树(分解分母)忠实执行,MASTer 项目扩展段锚如实
|
|
28
|
+
分流 extra_master_sections 不计入强度判定;
|
|
29
|
+
- enforcement 轴(R2 MUST 通胀缓解):每条 policy 物料带 x-b6-porting.source_sections
|
|
30
|
+
(12 段闭包内的 MASTer 行锚段映射),主锚语义断言——全部锚 ∈ {SHOULD, Change
|
|
31
|
+
Policy} → enforcement 必须 advisory(禁升 required);锚含 MUST/MUST NOT →
|
|
32
|
+
required_when_applicable(多锚卡主锚定强度;强度只降不升)。由
|
|
33
|
+
packages/cli/tests/catalog-b6-porting.spec.ts 机器断言(不靠自觉);逆向规则同钉
|
|
34
|
+
(source_sections 无 MUST/MUST NOT → 禁 required——防工具 biconditional 未来变更
|
|
35
|
+
漏拦);B6b-II 起锚证据不足(无 12 段锚 / advisory 池锚段出建议段闭包)的池卡
|
|
36
|
+
同法保守排除留池待复核(index.md 卡天然无 12 段锚——index 非 12 段结构文件);
|
|
37
|
+
- D5 保守精选(上限 25/批内执行):required 池 = 各批分母内未物化 ELIGIBLE 卡按池
|
|
38
|
+
密度序取前 22,逐卡 MASTer 行锚验证(行锚不落 MUST/MUST NOT 或全落项目扩展段的
|
|
39
|
+
卡保守排除留池待复核——池 enforcement 判定与锚证据矛盾时不猜 Owner 意图);
|
|
40
|
+
advisory 池 = SHOULD 源 canonical_backlog policy 卡按同公式密度序取前 3(锚段
|
|
41
|
+
全落建议段闭包方入选);每批合计 25;幂等重演:磁盘上 x-b6-porting.batch==本批
|
|
42
|
+
的条目原位收编(名单锁定),其余池卡按同规则补位;
|
|
43
|
+
- A1 档位语义:46 文件 vendor 正文零 MINIMAL/LIGHT/STANDARD 判档叙述(grep 实测
|
|
44
|
+
零命中)→ A1 清洗登记为空集;R8 词形清洗(**已执行**——裁决 12/D5 授权内容
|
|
45
|
+
演进批次,2026-09-05):协议件 'finish 流程' 3 处(01 vendor L25/L33、03 vendor
|
|
46
|
+
L35)+ index.md vendor L47 Trellis 任务机制叙述行(task.py add-context /
|
|
47
|
+
implement.jsonl / check.jsonl)与 L72/L75 'finish' 词形——按 R8_CLEANLINES /
|
|
48
|
+
INDEX_R8_CLEANLINES 整行替换清洗(逐条计数断言漂移即爆;'finish' → '收口
|
|
49
|
+
(closeout)',vNext 对应命令面 pomaster closeout;Trellis 机制行 → pomaster
|
|
50
|
+
context compile 投影语义);未登记词形/段零触碰(其余正文仍逐字节 == vendor);
|
|
51
|
+
index.md 为唯一授权词形适配点——自指路径 `.trellis/spec/frontend/`(L44,注入
|
|
52
|
+
矩阵段使用说明)按提案适配 vNext 播种面词形 `.pomaster/specs/hard/frontend/`
|
|
53
|
+
(whitelist 单点、计数断言)。清洗前后对照记录在 porting_notes(清单钉)。
|
|
54
|
+
|
|
55
|
+
用法:
|
|
56
|
+
python seed_b6b_frontend.py # 物化(write_if_changed 幂等)
|
|
57
|
+
python seed_b6b_frontend.py --verify # 只读重演(字节逐等比对)
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
import hashlib
|
|
61
|
+
import io
|
|
62
|
+
import json
|
|
63
|
+
import os
|
|
64
|
+
import re
|
|
65
|
+
import sys
|
|
66
|
+
|
|
67
|
+
import yaml
|
|
68
|
+
|
|
69
|
+
if __name__ == "__main__":
|
|
70
|
+
try:
|
|
71
|
+
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
|
|
72
|
+
except Exception:
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
HERE = os.path.dirname(os.path.abspath(__file__)) # .../POMaster_VNext/catalog/tools
|
|
76
|
+
VNEXT = os.path.dirname(os.path.dirname(HERE)) # .../POMaster_VNext
|
|
77
|
+
REPO = os.path.dirname(VNEXT) # d:/Vscode Documents/po-master
|
|
78
|
+
VENDOR_DIR = os.path.join(REPO, "pomaster", "components", "frontend-hard-spec",
|
|
79
|
+
"assets", "universal")
|
|
80
|
+
# 池卡行号锚的分母是 MASTer 消费树(SPEC-D 分解只读源)——段映射与 LCS 审计按
|
|
81
|
+
# MASTer 行号忠实执行;vendor 侧只承载播种字节 pin(R1 双分母如实标注)。
|
|
82
|
+
# MASTer_master 与本仓平级(d:/Vscode Documents/MASTer_master)。
|
|
83
|
+
MASTER_DIR = os.path.join(os.path.dirname(REPO), "MASTer_master", ".trellis", "spec",
|
|
84
|
+
"frontend")
|
|
85
|
+
SEEDS_DIR = os.path.join(VNEXT, "packages", "cli", "seeds")
|
|
86
|
+
ASSET_DIR = os.path.join(SEEDS_DIR, "specs", "hard", "frontend")
|
|
87
|
+
MANIFEST_PATH = os.path.join(SEEDS_DIR, "manifest.json")
|
|
88
|
+
POOL_PATH = os.path.join(VNEXT, "corpus", "spec-knowledge", "candidates",
|
|
89
|
+
"consolidated-pool.yaml")
|
|
90
|
+
CAND_DIR = os.path.join(VNEXT, "corpus", "spec-knowledge", "candidates")
|
|
91
|
+
POLICY_DIR = os.path.join(VNEXT, "catalog", "policies")
|
|
92
|
+
|
|
93
|
+
BATCH = "B6B-2"
|
|
94
|
+
MANIFEST_SCHEMA = "pomaster.seed-manifest/1"
|
|
95
|
+
BATCH_SCOPE = ("B6b-II:FE 46 文件分母后半(24-45 编号协议 + index.md;"
|
|
96
|
+
"01-23 已 B6b-I 在册——清单合并承载全量分母)")
|
|
97
|
+
PLANTED_TOTAL = 46
|
|
98
|
+
# 两批分母(B6b-I:01..23 已落地;B6b-II:24..45 + index——播种件 seed_version
|
|
99
|
+
# 按所属批记(B6b-I 件不重写,重算确定性逐字节不变);清单合并承载 46 条全量分母。
|
|
100
|
+
BATCHES = {
|
|
101
|
+
"B6B-1": [f"{n:02d}" for n in range(1, 24)],
|
|
102
|
+
"B6B-2": [f"{n:02d}" for n in range(24, 46)] + ["index"],
|
|
103
|
+
}
|
|
104
|
+
INDEX_NAME = "index.md"
|
|
105
|
+
|
|
106
|
+
AUTHORITY_SCOPE = "mixed_required_and_advisory"
|
|
107
|
+
LANE = "frontend"
|
|
108
|
+
|
|
109
|
+
# R1 漂移对账锚(spec-inventory.yaml pilot_verification 钉死 vendor sha256;
|
|
110
|
+
# 各批分母内漂移文件在清单——pin 全等对账通过 = 取材确为 vendor 字节非 MASTer。
|
|
111
|
+
# B6b-II 收紧:全等断言,去 64-bit 截断回退(截断回退允许前 16 hex 撞库假绿——
|
|
112
|
+
# 取材分母漂移必须在工具侧即爆)。
|
|
113
|
+
PILOT_VENDOR_SHA = {
|
|
114
|
+
"06-change-governance-protocol.md":
|
|
115
|
+
"2f19b46e451153cab35e9fb511d9da0f072f86424e7d3f7a6b307cd17a9d1b32",
|
|
116
|
+
"15-request-api-protocol.md":
|
|
117
|
+
"b9489d69e35a19b8d5ba2442108190e7b99989ef471c8cf413d9e4e408ca2969",
|
|
118
|
+
"30-data-grid-protocol.md":
|
|
119
|
+
"c702a9956fd5e7aac40e1eefebcdd7a3518b95bd1a750bfcb31cbaddb80f41ff",
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# R8 词形清洗台账(裁决 12/D5 授权内容演进批次,2026-09-05 执行):
|
|
123
|
+
# - 清洗记录(porting_notes 承载,前后对照留痕)+ 清洗表(R8_CLEANLINES /
|
|
124
|
+
# INDEX_R8_CLEANLINES——整行替换 + 逐条计数断言,vendor 漂移即爆);
|
|
125
|
+
# - 最小改写纪律:只动登记过的词形/行,其余正文仍逐字节 == vendor。
|
|
126
|
+
PORTING_NOTES = {
|
|
127
|
+
"01-development-checklist-protocol.md": [
|
|
128
|
+
"R8 词形清洗(已执行,裁决 12/D5 授权内容演进批次,2026-09-05):vendor L25 "
|
|
129
|
+
"'finish 流程' → '收口(closeout)流程'、L33 'finish' → '收口'(旧包任务完结"
|
|
130
|
+
"流程词形;vNext 对应物 = pomaster closeout 任务收口)。原登记(B6b-I):旧包"
|
|
131
|
+
"流程词形,vNext 无对应命令——内容忠实红线保留待授权清洗(已由本批清洗收口)",
|
|
132
|
+
],
|
|
133
|
+
"03-acceptance-gate-protocol.md": [
|
|
134
|
+
"R8 词形清洗(已执行,裁决 12/D5,2026-09-05):vendor L35 'finish' → "
|
|
135
|
+
"'收口(closeout)'(同 01 文件口径——pomaster closeout 对应物)。原登记"
|
|
136
|
+
"(B6b-I):旧包流程词形保留待授权清洗(已由本批清洗收口)",
|
|
137
|
+
],
|
|
138
|
+
"index.md": [
|
|
139
|
+
"R8 词形适配(唯一授权适配点,注入矩阵段使用说明):L44 自指路径 '.trellis/spec/"
|
|
140
|
+
"frontend/' 按提案适配 vNext 播种面词形 '.pomaster/specs/hard/frontend/'"
|
|
141
|
+
"(whitelist 单点替换、计数断言;其余正文逐字节保留)",
|
|
142
|
+
"R8 词形清洗(已执行,裁决 12/D5,2026-09-05):vendor L47 Trellis 任务机制"
|
|
143
|
+
"叙述整行改写——'在 Trellis Phase 1.3 使用原生 task.py add-context,把所选文件"
|
|
144
|
+
"分别加入当前 task 的 implement.jsonl 和 check.jsonl;不得修改 Trellis 脚本、"
|
|
145
|
+
"hook 或配置来实现自动加载。' → '所选协议(semantic ID 形态)以 vNext 上下文"
|
|
146
|
+
"投影承载:pomaster context compile --role <role> 按 role/capability "
|
|
147
|
+
"applicability 检索激活;不得修改 pomaster 工具、hook 或配置来实现自动加载。'"
|
|
148
|
+
"(旧机制叙述删除,pomaster 命令面真实存在)。原登记(B6b-II):旧包任务机制"
|
|
149
|
+
"词形保留待授权清洗(已由本批清洗收口)",
|
|
150
|
+
"R8 词形清洗(已执行,裁决 12/D5,2026-09-05):vendor L72 'finish 流程' → "
|
|
151
|
+
"'收口(closeout)流程'、L75 '归档、finish、发布记录' → '归档、收口、发布记录'"
|
|
152
|
+
"(pomaster closeout 对应物,同 01 文件口径)。原登记(B6b-II):旧包流程词形"
|
|
153
|
+
"保留待授权清洗(已由本批清洗收口)",
|
|
154
|
+
"R8 词形清洗(已执行,裁决 12/D5 同类授权延伸,裁定批 F,2026-09-05):index "
|
|
155
|
+
"注入机制叙述残留 13 行 vNext 化——'注入矩阵/任务注入矩阵'→'命中矩阵/任务命中"
|
|
156
|
+
"矩阵'(沿批 C BE index 段名词形惯例)、段名 '默认注入基线'→'默认激活基线'、"
|
|
157
|
+
"'按任务追加注入'→'按任务追加激活'(两段名的 Checklist 引用随改)、'默认注入/"
|
|
158
|
+
"强制注入/可不注入/注入优先级/实际注入'→'激活'词形、'重跑注入'→'重跑播种"
|
|
159
|
+
"(init)'(seed-once 语义句保留)。协议地图/追加矩阵行数据零触碰。原登记"
|
|
160
|
+
"(B6b-II):未登记注入叙述段留待授权清洗(本批收口)",
|
|
161
|
+
],
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# index.md 注入矩阵段 vNext 词形适配(提案 §4 B6b 行授权的唯一内容适配文件)。
|
|
165
|
+
# 仅路径词形:vendor 自指路径在 vNext 消费项目不存在,播种面为 .pomaster/specs/hard/
|
|
166
|
+
# frontend/。替换逐条计数断言(漂移即爆,禁静默零替换)。
|
|
167
|
+
INDEX_ADAPTATIONS = [
|
|
168
|
+
(".trellis/spec/frontend/", ".pomaster/specs/hard/frontend/", 1),
|
|
169
|
+
]
|
|
170
|
+
|
|
171
|
+
# R8 词形清洗表(裁决 12/D5 授权内容演进批次,2026-09-05 执行):整行替换 +
|
|
172
|
+
# 逐条计数断言(vendor 漂移即爆,禁静默零替换);未列文件正文仍逐字节 == vendor。
|
|
173
|
+
# 对照记录(前后词形)在 PORTING_NOTES;测试镜像钉在
|
|
174
|
+
# packages/cli/tests/seed-manifest.spec.ts(清洗后基线)。
|
|
175
|
+
R8_CLEANLINES = {
|
|
176
|
+
"01-development-checklist-protocol.md": [
|
|
177
|
+
("- 开发后、任务关闭或 finish 流程前必须完成 Spec Update Review。\n",
|
|
178
|
+
"- 开发后、任务关闭或收口(closeout)流程前必须完成 Spec Update Review。\n", 1),
|
|
179
|
+
("- MUST NOT 跳过 Spec Update Review 后直接归档、finish 或发布。\n",
|
|
180
|
+
"- MUST NOT 跳过 Spec Update Review 后直接归档、收口或发布。\n", 1),
|
|
181
|
+
],
|
|
182
|
+
"03-acceptance-gate-protocol.md": [
|
|
183
|
+
("- MUST NOT 将 finish、归档、发布记录当作 Spec Update Review 的替代品。\n",
|
|
184
|
+
"- MUST NOT 将收口(closeout)、归档、发布记录当作 Spec Update Review 的替代品。\n", 1),
|
|
185
|
+
],
|
|
186
|
+
}
|
|
187
|
+
INDEX_R8_CLEANLINES = [
|
|
188
|
+
("- [ ] 在 Trellis Phase 1.3 使用原生 `task.py add-context`,把所选文件分别加入当前"
|
|
189
|
+
" task 的 `implement.jsonl` 和 `check.jsonl`;不得修改 Trellis 脚本、hook 或配置来"
|
|
190
|
+
"实现自动加载。\n",
|
|
191
|
+
"- [ ] 所选协议(semantic ID 形态)以 vNext 上下文投影承载:`pomaster context "
|
|
192
|
+
"compile --role <role>` 按 role/capability applicability 检索激活;不得修改 "
|
|
193
|
+
"pomaster 工具、hook 或配置来实现自动加载。\n", 1),
|
|
194
|
+
("- 每次开发完成后、任务关闭或 finish 流程前,MUST 进行一次 Spec Update Review。\n",
|
|
195
|
+
"- 每次开发完成后、任务关闭或收口(closeout)流程前,MUST 进行一次 Spec Update "
|
|
196
|
+
"Review。\n", 1),
|
|
197
|
+
("- Spec Update Review 的输出属于验收证据;不得把归档、finish、发布记录当成 spec "
|
|
198
|
+
"review 的替代品。\n",
|
|
199
|
+
"- Spec Update Review 的输出属于验收证据;不得把归档、收口、发布记录当成 spec "
|
|
200
|
+
"review 的替代品。\n", 1),
|
|
201
|
+
# ---- 裁定批 F(D5 同类授权延伸,2026-09-05):index 注入机制叙述残留 13 行 vNext 化。
|
|
202
|
+
# 词形惯例沿批 C BE index 清洗(注入→激活/命中、重跑注入→重跑播种);矩阵行数据零触碰。
|
|
203
|
+
("- 新增、废弃、合并或拆分属于协议架构变更,必须更新索引、注入矩阵、职责边界和目录"
|
|
204
|
+
"验证;已发布文件先废弃和迁移,不得静默删除或复用其 ID。\n",
|
|
205
|
+
"- 新增、废弃、合并或拆分属于协议架构变更,必须更新索引、命中矩阵、职责边界和目录"
|
|
206
|
+
"验证;已发布文件先废弃和迁移,不得静默删除或复用其 ID。\n", 1),
|
|
207
|
+
("1. 默认注入 P0 基线和任务命中的专项协议。\n",
|
|
208
|
+
"1. 默认激活 P0 基线和任务命中的专项协议。\n", 1),
|
|
209
|
+
("- [ ] 读取「默认注入基线」,再按「按任务追加注入」选择本次命中的协议;多行命中取"
|
|
210
|
+
"并集。\n",
|
|
211
|
+
"- [ ] 读取「默认激活基线」,再按「按任务追加激活」选择本次命中的协议;多行命中取"
|
|
212
|
+
"并集。\n", 1),
|
|
213
|
+
("| P0 | 治理、安全、环境和跨层契约底座 | 默认注入;失败即阻塞开发或放行 |\n",
|
|
214
|
+
"| P0 | 治理、安全、环境和跨层契约底座 | 默认激活;失败即阻塞开发或放行 |\n", 1),
|
|
215
|
+
("| P1 | 核心架构、数据、UI 和高频工程协议 | 命中场景时强制注入;不得降级为建议 |\n",
|
|
216
|
+
"| P1 | 核心架构、数据、UI 和高频工程协议 | 命中场景时强制激活;不得降级为建议 |\n", 1),
|
|
217
|
+
("| P2 | 发布、运营、兼容和协作完善协议 | 命中场景时强制执行;未命中可不注入 |\n",
|
|
218
|
+
"| P2 | 发布、运营、兼容和协作完善协议 | 命中场景时强制执行;未命中可不激活 |\n", 1),
|
|
219
|
+
("P2 表示默认注入优先级较低,不表示协议中的 MUST 可以忽略。\n",
|
|
220
|
+
"P2 表示默认激活优先级较低,不表示协议中的 MUST 可以忽略。\n", 1),
|
|
221
|
+
("与任务注入矩阵,保持双向索引完整。\n",
|
|
222
|
+
"与任务命中矩阵,保持双向索引完整。\n", 1),
|
|
223
|
+
("重跑注入默认只补齐缺失文件、不覆盖已存在的协议,所以就地维护不会被覆盖。\n",
|
|
224
|
+
"重跑播种(init)默认只补齐缺失文件、不覆盖已存在的协议,所以就地维护不会被覆盖。\n", 1),
|
|
225
|
+
("## 默认注入基线\n", "## 默认激活基线\n", 1),
|
|
226
|
+
("使用本规范时默认注入:\n", "使用本规范时默认激活:\n", 1),
|
|
227
|
+
("## 按任务追加注入\n", "## 按任务追加激活\n", 1),
|
|
228
|
+
("同一任务命中多行时取并集;数字用于查表,实际注入必须使用文档 ID。\n",
|
|
229
|
+
"同一任务命中多行时取并集;数字用于查表,实际激活必须使用文档 ID。\n", 1),
|
|
230
|
+
]
|
|
231
|
+
|
|
232
|
+
LCS_THRESHOLD = 20
|
|
233
|
+
ADVISORY_CAP = 3
|
|
234
|
+
REQUIRED_CAP = 22
|
|
235
|
+
CURATED_CAP = REQUIRED_CAP + ADVISORY_CAP # 25 = D5 上限
|
|
236
|
+
# D6 TP 口径(Owner 裁决 12①,2026-09-05):D5 上限 25/批自此对 TECHNOLOGY_PROFILE
|
|
237
|
+
# 登记面一并计入(未来批 TP+policy 合并判卷,不再豁免)。FE 移植无 TP 面,本工具
|
|
238
|
+
# 批合计恒 = 25;B6c 已落 10 条 TP 为 Owner 追认例外维持现状(钉在
|
|
239
|
+
# seed_b6c_backend.py D5_CAP_PER_BATCH/GRANDFATHERED_TP_B6C +
|
|
240
|
+
# tests/integration/catalog-b6-porting.spec.ts D6 describe)。
|
|
241
|
+
|
|
242
|
+
GROUPS = ["FE-G1", "FE-G2", "FE-G3", "FE-G4"]
|
|
243
|
+
# B6b-I 分母前缀(01-23;池卡 source_protocol 词形)
|
|
244
|
+
FE23_PREFIXES = tuple(f".trellis/spec/frontend/{n:02d}-" for n in range(1, 24))
|
|
245
|
+
# B6b-II 分母(24-45 + index.md——池卡 source_protocol 词形;index 卡行锚天然落
|
|
246
|
+
# index 自有段结构(12 段闭包外),required/advisory 池按锚证据保守排除)
|
|
247
|
+
FE2_DENOM_PREFIXES = tuple(f".trellis/spec/frontend/{n:02d}-" for n in range(24, 46))
|
|
248
|
+
INDEX_PROTOCOL = ".trellis/spec/frontend/index.md"
|
|
249
|
+
POOL_REL = "POMaster_VNext/corpus/spec-knowledge/candidates/consolidated-pool.yaml"
|
|
250
|
+
|
|
251
|
+
CLEAN_ROOM_NOTE = ("independently rewritten from SPEC-D decomposition candidate cards; "
|
|
252
|
+
"zero verbatim copy")
|
|
253
|
+
|
|
254
|
+
# x-vocab-pr resolution 转正词形(裁定批 B/D4=vocab PR-0009 落地,2026-09-05;裁定批 F
|
|
255
|
+
# 工具-目录漂移修复纳入 builder 常量——ADR:常量纳编而非 merge_preserving,保工具单源
|
|
256
|
+
# 重演语义,最小改动;与 catalog/policies 在册条目 resolution 逐字节一致)。
|
|
257
|
+
VOCAB_PR_RESOLUTION_POLICY = (
|
|
258
|
+
"2026-09-05 vocab PR-0009 收编落地(vocab-lock@v0.8-resolved,三镜像同 commit;"
|
|
259
|
+
"Owner 裁定 D4=(a) 2026-09-05):kind='policy' 是 catalog 物料分类词形"
|
|
260
|
+
"(catalog_layer_vocab.catalog_kind 在册——PR-0006,不受 kinds_registry.truth_bodies "
|
|
261
|
+
"闭包管辖),POLICY. 前缀为 governed 闭包既有前缀,id 域段词形随 "
|
|
262
|
+
"catalog_layer_vocab.policy_id_domains / policy_web_domains 收编;本 pending 注记就此"
|
|
263
|
+
"转正(finding/proposal/locked_vocab_untouched 为创建时点历史记录原样保留——"
|
|
264
|
+
"mcp_eyes 先例)"
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
# 物化层 clean-room 改写(materialize-curated.py REWRITE_TEXT 同款机制):
|
|
268
|
+
# 卡层 statement 与上游源文存在逐字重合(LCS>=20 字审计失败)时,在此以独立措辞改写,
|
|
269
|
+
# 语义等价;改写卡在 x-spec-d-materialization.clean_room_rewrite 标记。
|
|
270
|
+
REWRITE_TEXT = {
|
|
271
|
+
"POLICY.DEP.BUILD_PATH_SUPPLY_CHAIN":
|
|
272
|
+
"凡在构建与集成链路上执行的自动化环节——无论是构建期插件、流水线步骤、代码生成"
|
|
273
|
+
"过程还是远端脚本——一律纳入供应链同级审查;对可漂移的引用形态必须消除,改为锁定"
|
|
274
|
+
"版本或在受控策略下更新。",
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
# 池自证锚(输入漂移 fail-closed;与 consolidate_pool.py 输出对账)
|
|
278
|
+
EXPECT_ELIGIBLE = 180
|
|
279
|
+
EXPECT_CANONICAL = 895
|
|
280
|
+
EXPECT_ABSORBED = 175
|
|
281
|
+
EXPECT_TOTAL = 1070
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
# ======================================================================
|
|
285
|
+
# 人工审定 clean-room 常量(title / en_keywords / review_notes / 新 id 域段)
|
|
286
|
+
# ======================================================================
|
|
287
|
+
TITLES = {
|
|
288
|
+
"POLICY.CONTRACT.NO_INVENTED_FACTS": "未证实事实先补契约",
|
|
289
|
+
"POLICY.GATE.RISK_FACTORS_CONFIRMED": "放行前风险因素逐项确认",
|
|
290
|
+
"POLICY.BOUNDARY.VALIDATE_IN_ENCODE_OUT": "不可信数据入口校验出口编码",
|
|
291
|
+
"POLICY.DEP.BUILD_PATH_SUPPLY_CHAIN": "构建链路按供应链治理",
|
|
292
|
+
"POLICY.TOOL.NO_VENDORED_BODY_EDITS": "禁改第三方工具正文消误报",
|
|
293
|
+
"POLICY.GUARD.NO_CHECK_WEAKENING": "检查弱化禁令与最小例外留痕",
|
|
294
|
+
"POLICY.SEC.NO_SECRETS_IN_CLIENT_SURFACE": "秘密不落客户端可见面",
|
|
295
|
+
"POLICY.AI.FACT_INFERENCE_SEPARATION": "事实推断待确认三分标注",
|
|
296
|
+
"POLICY.SEC.NO_LONGTERM_SECURITY_DISABLE": "安全机制关闭须有期限",
|
|
297
|
+
"POLICY.REGISTRY.HUMAN_FIELDS_VALIDATED_DECORRELATED": "人工裁决字段独立校验",
|
|
298
|
+
"POLICY.SEC.NO_SCRIPT_READABLE_CREDENTIALS": "凭据不落脚本可读存储",
|
|
299
|
+
"POLICY.GATE.P0_NON_BYPASSABLE": "最高级门禁不可绕过",
|
|
300
|
+
"POLICY.TEST.ISOLATION_AND_CLEANUP": "测试隔离与收尾清理",
|
|
301
|
+
"POLICY.SEC.AUTHN_POLICY_UNIFIED": "认证凭据策略统一定义",
|
|
302
|
+
"POLICY.SEC.URL_SOURCE_ALLOWLIST": "跳转与资源地址限定受信来源",
|
|
303
|
+
"POLICY.AI.CHANGE_PLAN_FIRST": "AI 编码先出变更计划",
|
|
304
|
+
"POLICY.ROLE.HUMAN_SIGNS_FOR_AI": "AI 产出人类签核",
|
|
305
|
+
"POLICY.TEST.STABLE_OBSERVABLE_ASSERTIONS": "测试断言可观察行为",
|
|
306
|
+
"POLICY.PROC.SCOPE_DRIFT_RECLASSIFY": "范围漂移暂停重分类",
|
|
307
|
+
"POLICY.SEC.UPLOAD_DOWNLOAD_SERVER_RECHECK": "上传下载服务端复验",
|
|
308
|
+
"POLICY.CFG.PRODUCTION_SAFE_DEFAULTS": "生产环境安全默认态",
|
|
309
|
+
"POLICY.CFG.SCHEMA_BACKED_CONFIG": "配置结构化定义与环境矩阵",
|
|
310
|
+
"POLICY.CHG.NO_UNRELATED_CHANGES": "变更不夹带无关改动",
|
|
311
|
+
"POLICY.TEST.PYRAMID_AND_CI_MATRIX": "测试金字塔与持续集成矩阵",
|
|
312
|
+
"POLICY.PROC.CHECKLIST_CHANGE_POLICY": "检查清单条目变更纪律",
|
|
313
|
+
"POLICY.AI.RULE_RELAXATION_APPROVAL": "AI 禁令放宽双重批准",
|
|
314
|
+
# ---- B6b-II(FE 24-45 + index 分母;D5 25/批内执行)----
|
|
315
|
+
"POLICY.FLAG.LIFECYCLE_METADATA": "功能开关登记六要素与期限",
|
|
316
|
+
"POLICY.OBS.NO_SENSITIVE_RAW_VALUES": "遥测不携带敏感原值",
|
|
317
|
+
"POLICY.OBS.TELEMETRY_LIFECYCLE_DECLARED": "遥测事件生命周期声明",
|
|
318
|
+
"POLICY.FLAG.CLEANUP_AFTER_FULL_ROLLOUT": "全量后清理开关旧路径",
|
|
319
|
+
"POLICY.WEB.TRACK.NO_SYNTHETIC_ACTIONS": "程序行为不记作用户操作",
|
|
320
|
+
"POLICY.FLAG.CONSISTENT_OFF_STATE": "开关关闭态全链路停用",
|
|
321
|
+
"POLICY.OBS.CONTEXT_FIELD_BASELINE": "日志定位字段基线",
|
|
322
|
+
"POLICY.WEB.TRACK.ATTEMPT_RESULT_CORRELATION": "操作发起与结果成对关联",
|
|
323
|
+
"POLICY.REL.TRACEABLE_BUILD": "构建携带可溯版本标识",
|
|
324
|
+
"POLICY.WEB.I18N.RAW_VALUE_FOR_COMPUTE": "计算排序用原始值",
|
|
325
|
+
"POLICY.FLAG.NOT_A_PERMISSION": "开关不承载权限语义",
|
|
326
|
+
"POLICY.OBS.SOURCE_MAP_ACCESS_CONTROL": "压缩映射受权限保护",
|
|
327
|
+
"POLICY.OBS.ALERT_WITH_OWNER": "关键告警带明确责任人",
|
|
328
|
+
"POLICY.REL.OBSERVABILITY_BEFORE_SHIP": "监控与映射发布前就位",
|
|
329
|
+
"POLICY.WEB.COPY.ERROR_NEXT_STEP": "错误文案三要素齐备",
|
|
330
|
+
"POLICY.WEB.COPY.ACTION_OBJECT_CLARITY": "操作文案动作对象明确",
|
|
331
|
+
"POLICY.WEB.HANDOFF.STATE_MATRIX_FULL": "设计交付完整状态矩阵",
|
|
332
|
+
"POLICY.WEB.COPY.ENUMERABLE_PLACEMENT": "用户可见文案静态可枚举",
|
|
333
|
+
"POLICY.WEB.PAGE.REGION_CONSISTENCY": "同类页面区域位置一致",
|
|
334
|
+
"POLICY.WEB.COMP.PUBLIC_CONTRACT_COMPLETENESS": "公共组件契约完备",
|
|
335
|
+
"POLICY.WEB.COMP.NO_TRIVIAL_OR_GOD_COMPONENT": "禁琐碎包装与万能组件",
|
|
336
|
+
"POLICY.WEB.I18N.COPY_KEY_DISCIPLINE": "文案稳定键引用纪律",
|
|
337
|
+
"POLICY.OBS.TRACE_CORRELATION": "追踪标识全链路关联",
|
|
338
|
+
"POLICY.WEB.TRACK.TYPED_CLIENT_VALIDATION": "类型化采集客户端与校验",
|
|
339
|
+
"POLICY.FLAG.KILL_SWITCH": "关键写操作紧急停用开关",
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
KEYWORDS = {
|
|
343
|
+
"POLICY.CONTRACT.NO_INVENTED_FACTS": [
|
|
344
|
+
"no invented facts", "missing contract", "block on confirmation", "no guessed values",
|
|
345
|
+
],
|
|
346
|
+
"POLICY.GATE.RISK_FACTORS_CONFIRMED": [
|
|
347
|
+
"release risk confirmation", "contract frozen", "rollback available", "no go past red",
|
|
348
|
+
],
|
|
349
|
+
"POLICY.BOUNDARY.VALIDATE_IN_ENCODE_OUT": [
|
|
350
|
+
"validate input encode output", "untrusted data boundary", "types are not validation",
|
|
351
|
+
],
|
|
352
|
+
"POLICY.DEP.BUILD_PATH_SUPPLY_CHAIN": [
|
|
353
|
+
"build supply chain", "ci actions as dependencies", "pinned references", "code generators",
|
|
354
|
+
],
|
|
355
|
+
"POLICY.TOOL.NO_VENDORED_BODY_EDITS": [
|
|
356
|
+
"no vendored body edits", "suppress false positives properly", "adapter or config layer",
|
|
357
|
+
],
|
|
358
|
+
"POLICY.GUARD.NO_CHECK_WEAKENING": [
|
|
359
|
+
"no check weakening", "no deleted tests", "no disabled rules", "minimal logged exception",
|
|
360
|
+
],
|
|
361
|
+
"POLICY.SEC.NO_SECRETS_IN_CLIENT_SURFACE": [
|
|
362
|
+
"no secrets in client", "no credentials in logs", "env file is not a vault",
|
|
363
|
+
],
|
|
364
|
+
"POLICY.AI.FACT_INFERENCE_SEPARATION": [
|
|
365
|
+
"fact inference separation", "todo confirm markers", "no on-the-spot invention",
|
|
366
|
+
],
|
|
367
|
+
"POLICY.SEC.NO_LONGTERM_SECURITY_DISABLE": [
|
|
368
|
+
"no permanent security disable", "timeboxed debug exception", "csp and cert validation",
|
|
369
|
+
],
|
|
370
|
+
"POLICY.REGISTRY.HUMAN_FIELDS_VALIDATED_DECORRELATED": [
|
|
371
|
+
"human fields independent validation", "generator decoupled assertion",
|
|
372
|
+
"no silent overwrite",
|
|
373
|
+
],
|
|
374
|
+
"POLICY.SEC.NO_SCRIPT_READABLE_CREDENTIALS": [
|
|
375
|
+
"no script readable credentials", "refresh token storage", "approved timeboxed exception",
|
|
376
|
+
],
|
|
377
|
+
"POLICY.GATE.P0_NON_BYPASSABLE": [
|
|
378
|
+
"p0 gate non bypassable", "no human override", "time pressure is not a reason",
|
|
379
|
+
],
|
|
380
|
+
"POLICY.TEST.ISOLATION_AND_CLEANUP": [
|
|
381
|
+
"test isolation", "cleanup credentials", "browser storage reset", "pending async cleanup",
|
|
382
|
+
],
|
|
383
|
+
"POLICY.SEC.AUTHN_POLICY_UNIFIED": [
|
|
384
|
+
"unified authn policy", "single token lifecycle", "no scattered session handling",
|
|
385
|
+
],
|
|
386
|
+
"POLICY.SEC.URL_SOURCE_ALLOWLIST": [
|
|
387
|
+
"url source allowlist", "safe protocols only", "no untrusted redirect",
|
|
388
|
+
],
|
|
389
|
+
"POLICY.AI.CHANGE_PLAN_FIRST": [
|
|
390
|
+
"change plan first", "read protocols before coding", "ai declared scope and validation",
|
|
391
|
+
],
|
|
392
|
+
"POLICY.ROLE.HUMAN_SIGNS_FOR_AI": [
|
|
393
|
+
"human signs for ai", "ai cannot approve", "no release sign off by ai",
|
|
394
|
+
],
|
|
395
|
+
"POLICY.TEST.STABLE_OBSERVABLE_ASSERTIONS": [
|
|
396
|
+
"observable assertions", "stable repeatable tests", "no implementation detail selectors",
|
|
397
|
+
],
|
|
398
|
+
"POLICY.PROC.SCOPE_DRIFT_RECLASSIFY": [
|
|
399
|
+
"scope drift reclassify", "pause and replan", "update change classification",
|
|
400
|
+
],
|
|
401
|
+
"POLICY.SEC.UPLOAD_DOWNLOAD_SERVER_RECHECK": [
|
|
402
|
+
"server side recheck", "upload download boundary", "client checks are not the boundary",
|
|
403
|
+
],
|
|
404
|
+
"POLICY.CFG.PRODUCTION_SAFE_DEFAULTS": [
|
|
405
|
+
"production safe defaults", "debug off in production", "explicit non production identity",
|
|
406
|
+
],
|
|
407
|
+
"POLICY.CFG.SCHEMA_BACKED_CONFIG": [
|
|
408
|
+
"schema backed config", "typed defaults", "required validation", "environment matrix",
|
|
409
|
+
],
|
|
410
|
+
"POLICY.CHG.NO_UNRELATED_CHANGES": [
|
|
411
|
+
"no unrelated changes", "no drive by refactor", "preserve unrelated edits",
|
|
412
|
+
],
|
|
413
|
+
"POLICY.TEST.PYRAMID_AND_CI_MATRIX": [
|
|
414
|
+
"test pyramid shape", "few high value e2e", "ci matrix pinning", "deterministic ci env",
|
|
415
|
+
],
|
|
416
|
+
"POLICY.PROC.CHECKLIST_CHANGE_POLICY": [
|
|
417
|
+
"checklist change policy", "trigger validation failure action", "downgrade needs approval",
|
|
418
|
+
],
|
|
419
|
+
"POLICY.AI.RULE_RELAXATION_APPROVAL": [
|
|
420
|
+
"ai rule relaxation approval", "dual owner sign off", "new mistake to protocol",
|
|
421
|
+
],
|
|
422
|
+
# ---- B6b-II ----
|
|
423
|
+
"POLICY.FLAG.LIFECYCLE_METADATA": [
|
|
424
|
+
"feature flag metadata", "owner and expiry", "no permanent temporary flag", "cleanup date",
|
|
425
|
+
],
|
|
426
|
+
"POLICY.OBS.NO_SENSITIVE_RAW_VALUES": [
|
|
427
|
+
"no sensitive raw values", "no credentials in telemetry", "no pii in breadcrumbs",
|
|
428
|
+
"no high cardinality identifiers",
|
|
429
|
+
],
|
|
430
|
+
"POLICY.OBS.TELEMETRY_LIFECYCLE_DECLARED": [
|
|
431
|
+
"telemetry event declaration", "schema version sampling", "retention deletion policy",
|
|
432
|
+
"telemetry failure non blocking",
|
|
433
|
+
],
|
|
434
|
+
"POLICY.FLAG.CLEANUP_AFTER_FULL_ROLLOUT": [
|
|
435
|
+
"cleanup after full rollout", "remove flag branches", "migrate to config system",
|
|
436
|
+
"record flag retirement",
|
|
437
|
+
],
|
|
438
|
+
"POLICY.WEB.TRACK.NO_SYNTHETIC_ACTIONS": [
|
|
439
|
+
"no synthetic actions", "rerender is not user action", "program retry excluded",
|
|
440
|
+
"real user intent only",
|
|
441
|
+
],
|
|
442
|
+
"POLICY.FLAG.CONSISTENT_OFF_STATE": [
|
|
443
|
+
"consistent off state", "hide entry route and requests", "no background calls when off",
|
|
444
|
+
],
|
|
445
|
+
"POLICY.OBS.CONTEXT_FIELD_BASELINE": [
|
|
446
|
+
"log context fields", "version env page trace id", "browser and timestamp fields",
|
|
447
|
+
],
|
|
448
|
+
"POLICY.WEB.TRACK.ATTEMPT_RESULT_CORRELATION": [
|
|
449
|
+
"attempt result correlation", "operation id pairing", "end to end pairing analysis",
|
|
450
|
+
],
|
|
451
|
+
"POLICY.REL.TRACEABLE_BUILD": [
|
|
452
|
+
"traceable build", "version identifier", "source commit traceability",
|
|
453
|
+
"no unlabeled release",
|
|
454
|
+
],
|
|
455
|
+
"POLICY.WEB.I18N.RAW_VALUE_FOR_COMPUTE": [
|
|
456
|
+
"raw value for compute", "formatted string not computable", "no sort on display text",
|
|
457
|
+
],
|
|
458
|
+
"POLICY.FLAG.NOT_A_PERMISSION": [
|
|
459
|
+
"flag is not permission", "dual gate flag and permission", "no business state in flags",
|
|
460
|
+
],
|
|
461
|
+
"POLICY.OBS.SOURCE_MAP_ACCESS_CONTROL": [
|
|
462
|
+
"source map access control", "one to one with version", "no public deployment",
|
|
463
|
+
],
|
|
464
|
+
"POLICY.OBS.ALERT_WITH_OWNER": [
|
|
465
|
+
"alert with owner", "error rate blank screen alert", "aggregation dimensions",
|
|
466
|
+
],
|
|
467
|
+
"POLICY.REL.OBSERVABILITY_BEFORE_SHIP": [
|
|
468
|
+
"observability before ship", "monitoring ready pre release", "no post release rebuild",
|
|
469
|
+
],
|
|
470
|
+
"POLICY.WEB.COPY.ERROR_NEXT_STEP": [
|
|
471
|
+
"error copy triad", "what happened recoverability next step", "no raw backend message",
|
|
472
|
+
],
|
|
473
|
+
"POLICY.WEB.COPY.ACTION_OBJECT_CLARITY": [
|
|
474
|
+
"action object clarity", "no vague verbs", "button copy names the object",
|
|
475
|
+
],
|
|
476
|
+
"POLICY.WEB.HANDOFF.STATE_MATRIX_FULL": [
|
|
477
|
+
"full state matrix", "no ideal state only", "table deliverable specs",
|
|
478
|
+
"clickable prototype",
|
|
479
|
+
],
|
|
480
|
+
"POLICY.WEB.COPY.ENUMERABLE_PLACEMENT": [
|
|
481
|
+
"statically enumerable copy", "template or copy catalog only", "no script literals",
|
|
482
|
+
],
|
|
483
|
+
"POLICY.WEB.PAGE.REGION_CONSISTENCY": [
|
|
484
|
+
"region consistency", "primary secondary action placement", "no monolithic page",
|
|
485
|
+
"consistent region order",
|
|
486
|
+
],
|
|
487
|
+
"POLICY.WEB.COMP.PUBLIC_CONTRACT_COMPLETENESS": [
|
|
488
|
+
"public component contract", "typed props events slots", "docs tests single entry",
|
|
489
|
+
"owner purpose non goals",
|
|
490
|
+
],
|
|
491
|
+
"POLICY.WEB.COMP.NO_TRIVIAL_OR_GOD_COMPONENT": [
|
|
492
|
+
"no trivial wrapper", "typed minimal props", "no god config object",
|
|
493
|
+
],
|
|
494
|
+
"POLICY.WEB.I18N.COPY_KEY_DISCIPLINE": [
|
|
495
|
+
"stable copy keys", "no display text as key", "no copy component duplication",
|
|
496
|
+
],
|
|
497
|
+
"POLICY.OBS.TRACE_CORRELATION": [
|
|
498
|
+
"trace correlation", "w3c trace context", "cross origin propagation trust",
|
|
499
|
+
],
|
|
500
|
+
"POLICY.WEB.TRACK.TYPED_CLIENT_VALIDATION": [
|
|
501
|
+
"typed analytics client", "schema validation", "quality monitoring",
|
|
502
|
+
],
|
|
503
|
+
"POLICY.FLAG.KILL_SWITCH": [
|
|
504
|
+
"kill switch", "emergency disable", "rollout rollback audit",
|
|
505
|
+
],
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
REVIEW_NOTES = {
|
|
509
|
+
"POLICY.CONTRACT.NO_INVENTED_FACTS": [
|
|
510
|
+
"与既有 POLICY.API.NO_INFORMAL_CONTRACT(接口契约不得来自非正式源)不同轴:本条管任何"
|
|
511
|
+
"未定义事实先补契约或阻塞确认,彼条管契约来源正式性;池层已判零语义重复。",
|
|
512
|
+
"卡为双锚卡(01 L22 + 02 L28 AI 侧禁止形态),02 文件不重复立卡。",
|
|
513
|
+
],
|
|
514
|
+
"POLICY.GATE.RISK_FACTORS_CONFIRMED": [
|
|
515
|
+
"与既有 GATE.CHG.PRECHANGE_CHECKS(变更前检查单)对象不同:本条是放行放行面的风险因素"
|
|
516
|
+
"确认义务,彼是变更前置检查;与既有 POLICY.REL.PRE_RELEASE_CONFIRMATION(发布前六项)"
|
|
517
|
+
"相邻——彼管发布时点、本管阶段放行,互引不合并。",
|
|
518
|
+
],
|
|
519
|
+
"POLICY.BOUNDARY.VALIDATE_IN_ENCODE_OUT": [
|
|
520
|
+
"安全数据边界义务在既有 143 条中无对应条目(POLICY.SEC.* 仅第三方执行体登记),零语义重复。",
|
|
521
|
+
"卡为双锚卡(04 L23 + 10 L27 外部数据运行时校验),10 文件不重复立卡。",
|
|
522
|
+
],
|
|
523
|
+
"POLICY.DEP.BUILD_PATH_SUPPLY_CHAIN": [
|
|
524
|
+
"与既有 POLICY.DEP.* 三条(准入/引入/变更面)为不同时点:本条管构建与 CI 链路按供应链"
|
|
525
|
+
"治理,彼三条管依赖包引入与变更;零语义重复。",
|
|
526
|
+
],
|
|
527
|
+
"POLICY.TOOL.NO_VENDORED_BODY_EDITS": [
|
|
528
|
+
"vendored 物料修复纪律在既有 143 条中无对应条目,零语义重复;statement 措辞为 lane 中性"
|
|
529
|
+
"(第三方工具/生成物通用)。",
|
|
530
|
+
],
|
|
531
|
+
"POLICY.GUARD.NO_CHECK_WEAKENING": [
|
|
532
|
+
"与既有 POLICY.SPEC.* 族无重叠(spec 治理 vs 检查强度治理);多锚卡(02 L30 + 10 L38/L84"
|
|
533
|
+
" + 20 L32),锚文件不重复立卡。",
|
|
534
|
+
],
|
|
535
|
+
"POLICY.SEC.NO_SECRETS_IN_CLIENT_SURFACE": [
|
|
536
|
+
"秘密面治理在既有 143 条中无对应条目,零语义重复;多锚卡(04 L36 + 05 L28/L31 环境配置"
|
|
537
|
+
"侧),05 文件不重复立卡。",
|
|
538
|
+
],
|
|
539
|
+
"POLICY.AI.FACT_INFERENCE_SEPARATION": [
|
|
540
|
+
"AI 输出认知纪律在既有 143 条中无对应条目(POLICY.ROLE.* 管签核权归属,不管事实/推断"
|
|
541
|
+
"标注),零语义重复。",
|
|
542
|
+
],
|
|
543
|
+
"POLICY.SEC.NO_LONGTERM_SECURITY_DISABLE": [
|
|
544
|
+
"安全机制临时关闭的期限治理在既有 143 条中无对应条目,零语义重复。",
|
|
545
|
+
],
|
|
546
|
+
"POLICY.REGISTRY.HUMAN_FIELDS_VALIDATED_DECORRELATED": [
|
|
547
|
+
"登记表人工字段完整性在既有 143 条中无对应条目(既有 REGISTRY 词形未用),零语义重复;"
|
|
548
|
+
"辅助锚点 09-module-boundary L103。",
|
|
549
|
+
],
|
|
550
|
+
"POLICY.SEC.NO_SCRIPT_READABLE_CREDENTIALS": [
|
|
551
|
+
"与 POLICY.SEC.NO_SECRETS_IN_CLIENT_SURFACE 同批相邻:彼管秘密不进可见产物面,本管登录态"
|
|
552
|
+
"凭据的存储介质边界(脚本可读性),互引不合并。",
|
|
553
|
+
],
|
|
554
|
+
"POLICY.GATE.P0_NON_BYPASSABLE": [
|
|
555
|
+
"门禁不可绕过原则在既有 143 条中无对应条目(既有 GATE.* 为 gate recipe 检查单,非绕过"
|
|
556
|
+
"禁令),零语义重复。",
|
|
557
|
+
],
|
|
558
|
+
"POLICY.TEST.ISOLATION_AND_CLEANUP": [
|
|
559
|
+
"测试隔离与清理在既有 143 条中无对应条目,零语义重复。",
|
|
560
|
+
],
|
|
561
|
+
"POLICY.SEC.AUTHN_POLICY_UNIFIED": [
|
|
562
|
+
"认证策略单一来源在既有 143 条中无对应条目(POLICY.WEB.API.SESSION_RECOVERY_SPLIT 管会话"
|
|
563
|
+
"恢复与权限拒绝拆分,不管凭据机制统一定义),零语义重复。",
|
|
564
|
+
],
|
|
565
|
+
"POLICY.SEC.URL_SOURCE_ALLOWLIST": [
|
|
566
|
+
"URL 来源受信治理在既有 143 条中无对应条目,零语义重复。",
|
|
567
|
+
],
|
|
568
|
+
"POLICY.AI.CHANGE_PLAN_FIRST": [
|
|
569
|
+
"AI 编码前置声明在既有 143 条中无对应条目(POLICY.PROC.PRE_CODE_DECLARATION 为 lane 中性"
|
|
570
|
+
"开工声明、适用任何实现者;本条管 AI 参与面的协议读取与计划产出义务),语义相邻互引不合并。",
|
|
571
|
+
],
|
|
572
|
+
"POLICY.ROLE.HUMAN_SIGNS_FOR_AI": [
|
|
573
|
+
"与既有 POLICY.ROLE.DOMAIN_DECISION_AUTHORITY(领域决定权不越位)不同轴:本条管 AI 产出"
|
|
574
|
+
"的人类签核义务,零语义重复。",
|
|
575
|
+
],
|
|
576
|
+
"POLICY.TEST.STABLE_OBSERVABLE_ASSERTIONS": [
|
|
577
|
+
"测试断言质量在既有 143 条中无对应条目,零语义重复。",
|
|
578
|
+
],
|
|
579
|
+
"POLICY.PROC.SCOPE_DRIFT_RECLASSIFY": [
|
|
580
|
+
"范围漂移处置在既有 143 条中无对应条目(POLICY.CHG.* 管已决策变更的过程纪律),零语义重复。",
|
|
581
|
+
],
|
|
582
|
+
"POLICY.SEC.UPLOAD_DOWNLOAD_SERVER_RECHECK": [
|
|
583
|
+
"文件传输服务端复验在既有 143 条中无对应条目,零语义重复;与 BOUNDARY.VALIDATE_IN_ENCODE_OUT"
|
|
584
|
+
" 为通则与特例关系(数据边界通则 vs 上传下载专项),互引。",
|
|
585
|
+
],
|
|
586
|
+
"POLICY.CFG.PRODUCTION_SAFE_DEFAULTS": [
|
|
587
|
+
"环境默认态治理在既有 143 条中无对应条目(POLICY.CFG 词形未用),零语义重复。",
|
|
588
|
+
],
|
|
589
|
+
"POLICY.CFG.SCHEMA_BACKED_CONFIG": [
|
|
590
|
+
"配置结构化定义在既有 143 条中无对应条目(POLICY.CFG 词形未用),零语义重复;"
|
|
591
|
+
"与同批物化的 POLICY.CFG.PRODUCTION_SAFE_DEFAULTS 义务正交(配置形状治理 vs 环境"
|
|
592
|
+
"默认态),互引不合并。",
|
|
593
|
+
],
|
|
594
|
+
"POLICY.CHG.NO_UNRELATED_CHANGES": [
|
|
595
|
+
"与既有 POLICY.CHG.* 族不同轴(彼管变更过程协同,本管变更内容纯净性);双锚卡(01 L32 +"
|
|
596
|
+
" 02 L15/L24),02 不重复立卡。",
|
|
597
|
+
],
|
|
598
|
+
"POLICY.TEST.PYRAMID_AND_CI_MATRIX": [
|
|
599
|
+
"advisory 物化(SHOULD 源):测试形态建议与 CI 矩阵确定性,源段 SHOULD——按八分类矩阵落"
|
|
600
|
+
" advisory 不升 required;enforcement 轴断言钉(catalog-b6-porting.spec)。",
|
|
601
|
+
],
|
|
602
|
+
"POLICY.PROC.CHECKLIST_CHANGE_POLICY": [
|
|
603
|
+
"advisory 物化(Change Policy 源):对协议自身检查清单的元规则(新增条目须带触发/验证/失败"
|
|
604
|
+
"动作),源段 Change Policy——advisory 落点;enforcement 轴断言钉。",
|
|
605
|
+
],
|
|
606
|
+
"POLICY.AI.RULE_RELAXATION_APPROVAL": [
|
|
607
|
+
"advisory 物化(Change Policy 源):AI 禁令放宽的批准元规则,源段 Change Policy——advisory"
|
|
608
|
+
" 落点;与 POLICY.SEC.RELAXATION_APPROVAL(安全放宽,同池未物化)不同域互引。",
|
|
609
|
+
],
|
|
610
|
+
# ---- B6b-II(零语义重复判定基准=B6b-I 落地后的 168 条;锚证据按 MASTer 行锚独立推导)----
|
|
611
|
+
"POLICY.FLAG.LIFECYCLE_METADATA": [
|
|
612
|
+
"功能开关生命周期登记在既有 168 条中无对应条目(FEATURE_ORIENTED 词形为组件形态轴),"
|
|
613
|
+
"零语义重复;双锚卡(36 L19+L29),36 文件不重复立卡。",
|
|
614
|
+
],
|
|
615
|
+
"POLICY.OBS.NO_SENSITIVE_RAW_VALUES": [
|
|
616
|
+
"遥测敏感数据边界在既有 168 条中无对应条目(SEC 族管客户端可见面与凭据存储介质,"
|
|
617
|
+
"不管遥测载荷),零语义重复;多锚卡(34 L22+L29/L33),34 文件不重复立卡。",
|
|
618
|
+
],
|
|
619
|
+
"POLICY.OBS.TELEMETRY_LIFECYCLE_DECLARED": [
|
|
620
|
+
"遥测事件治理元数据在既有 168 条中无对应条目,零语义重复;多锚卡(34 L24 MUST 锚 + "
|
|
621
|
+
"L54-L55 Checklist 锚同事实),主锚定强度 required。",
|
|
622
|
+
],
|
|
623
|
+
"POLICY.FLAG.CLEANUP_AFTER_FULL_ROLLOUT": [
|
|
624
|
+
"开关收尾清理在既有 168 条中无对应条目;与 POLICY.CHG.DEPRECATE_BEFORE_DELETE(先废弃"
|
|
625
|
+
"后删除)相邻——彼管通用废弃时序,本管开关生命周期终局,互引不合并;多锚卡(MUST/"
|
|
626
|
+
"MUST NOT + Change Policy 锚),主锚定强度 required。",
|
|
627
|
+
],
|
|
628
|
+
"POLICY.WEB.TRACK.NO_SYNTHETIC_ACTIONS": [
|
|
629
|
+
"行为事件真实性边界在既有 168 条中无对应条目,零语义重复。",
|
|
630
|
+
],
|
|
631
|
+
"POLICY.FLAG.CONSISTENT_OFF_STATE": [
|
|
632
|
+
"开关关闭态一致性在既有 168 条中无对应条目;与 FLAG.LIFECYCLE_METADATA 正交(彼管登记"
|
|
633
|
+
"元数据,本管关闭态行为),零语义重复;双锚卡(36 L20+L30),36 文件不重复立卡。",
|
|
634
|
+
],
|
|
635
|
+
"POLICY.OBS.CONTEXT_FIELD_BASELINE": [
|
|
636
|
+
"日志定位字段基线在既有 168 条中无对应条目,零语义重复。",
|
|
637
|
+
],
|
|
638
|
+
"POLICY.WEB.TRACK.ATTEMPT_RESULT_CORRELATION": [
|
|
639
|
+
"成对事件关联在既有 168 条中无对应条目,零语义重复。",
|
|
640
|
+
],
|
|
641
|
+
"POLICY.REL.TRACEABLE_BUILD": [
|
|
642
|
+
"构建可溯源性在既有 168 条中无对应条目;与 POLICY.DEP.BUILD_PATH_SUPPLY_CHAIN(B6b-I)"
|
|
643
|
+
"不同轴——彼管构建链路供应链治理,本管产物溯源标识,互引不合并。",
|
|
644
|
+
],
|
|
645
|
+
"POLICY.WEB.I18N.RAW_VALUE_FOR_COMPUTE": [
|
|
646
|
+
"原始值与显示值分离在既有 168 条中无对应条目(13 金额精度为金额特例未入册;本条为通用"
|
|
647
|
+
"形态),零语义重复。",
|
|
648
|
+
],
|
|
649
|
+
"POLICY.FLAG.NOT_A_PERMISSION": [
|
|
650
|
+
"开关与权限双判定边界在既有 168 条中无对应条目(17 权限协议面未入册;本条管开关不得"
|
|
651
|
+
"替代权限判定),零语义重复。",
|
|
652
|
+
],
|
|
653
|
+
"POLICY.OBS.SOURCE_MAP_ACCESS_CONTROL": [
|
|
654
|
+
"压缩映射访问控制在既有 168 条中无对应条目(SEC 族无 sourcemap 词形),零语义重复;"
|
|
655
|
+
"双锚卡(34 L21+L32),34 文件不重复立卡。",
|
|
656
|
+
],
|
|
657
|
+
"POLICY.OBS.ALERT_WITH_OWNER": [
|
|
658
|
+
"告警责任人义务在既有 168 条中无对应条目,零语义重复。",
|
|
659
|
+
],
|
|
660
|
+
"POLICY.REL.OBSERVABILITY_BEFORE_SHIP": [
|
|
661
|
+
"发布前可观测性就位在既有 168 条中无对应条目;与 POLICY.GATE.RISK_FACTORS_CONFIRMED"
|
|
662
|
+
"(B6b-I 放行面)相邻——彼管阶段放行风险确认,本管监控/映射前置物,互引不合并。",
|
|
663
|
+
],
|
|
664
|
+
"POLICY.WEB.COPY.ERROR_NEXT_STEP": [
|
|
665
|
+
"错误文案三要素在既有 168 条中无对应条目(WEB 错误态词族管组件与归一化,非文案面),"
|
|
666
|
+
"零语义重复;多锚卡(39 L19+L44/L46),39 文件不重复立卡。",
|
|
667
|
+
],
|
|
668
|
+
"POLICY.WEB.COPY.ACTION_OBJECT_CLARITY": [
|
|
669
|
+
"操作文案明确性在既有 168 条中无对应条目,零语义重复;双锚卡(39 L18+L47),39 文件"
|
|
670
|
+
"不重复立卡。",
|
|
671
|
+
],
|
|
672
|
+
"POLICY.WEB.HANDOFF.STATE_MATRIX_FULL": [
|
|
673
|
+
"设计交付状态矩阵完备性在既有 168 条中无对应条目,零语义重复;多锚卡(MUST/MUST NOT + "
|
|
674
|
+
"SHOULD 锚混合),主锚定强度 required——SHOULD 锚(可点击原型)不单独降级,锚证据混合"
|
|
675
|
+
"时以最强段定强度(B6b-I 轴规则)。",
|
|
676
|
+
],
|
|
677
|
+
"POLICY.WEB.COPY.ENUMERABLE_PLACEMENT": [
|
|
678
|
+
"文案落点静态可枚举在既有 168 条中无对应条目,零语义重复;多锚卡(39 L28-L36 展开),"
|
|
679
|
+
"39 文件不重复立卡。",
|
|
680
|
+
],
|
|
681
|
+
"POLICY.WEB.PAGE.REGION_CONSISTENCY": [
|
|
682
|
+
"页面区域位置一致性在既有 168 条中无对应条目(GRID 词族管表格数据面),零语义重复;"
|
|
683
|
+
"双锚卡(25 L20-L22+L77-L79),25 文件不重复立卡。",
|
|
684
|
+
],
|
|
685
|
+
"POLICY.WEB.COMP.PUBLIC_CONTRACT_COMPLETENESS": [
|
|
686
|
+
"公共组件契约完备性在既有 168 条中无对应条目,零语义重复;多锚卡(MUST + SHOULD 锚),"
|
|
687
|
+
"主锚定强度 required。",
|
|
688
|
+
],
|
|
689
|
+
"POLICY.WEB.COMP.NO_TRIVIAL_OR_GOD_COMPONENT": [
|
|
690
|
+
"组件形态禁令在既有 168 条中无对应条目(FEATURE_ORIENTED/MODULAR 为架构模式轴),"
|
|
691
|
+
"零语义重复。",
|
|
692
|
+
],
|
|
693
|
+
"POLICY.WEB.I18N.COPY_KEY_DISCIPLINE": [
|
|
694
|
+
"文案键纪律在既有 168 条中无对应条目,零语义重复;多锚卡(38 L20+L30-L31),38 文件"
|
|
695
|
+
"不重复立卡。",
|
|
696
|
+
],
|
|
697
|
+
"POLICY.OBS.TRACE_CORRELATION": [
|
|
698
|
+
"advisory 物化(SHOULD 源):追踪关联与 W3C Trace Context 跨源传播验证,源段 SHOULD——"
|
|
699
|
+
"按八分类矩阵落 advisory 不升 required;enforcement 轴断言钉(catalog-b6-porting.spec)。",
|
|
700
|
+
],
|
|
701
|
+
"POLICY.WEB.TRACK.TYPED_CLIENT_VALIDATION": [
|
|
702
|
+
"advisory 物化(SHOULD 源):类型化采集客户端与模式校验及质量监控,源段 SHOULD——"
|
|
703
|
+
"advisory 落点;enforcement 轴断言钉。",
|
|
704
|
+
],
|
|
705
|
+
"POLICY.FLAG.KILL_SWITCH": [
|
|
706
|
+
"advisory 物化(SHOULD 源):紧急停用开关配备,源段 SHOULD——advisory 落点;与 FLAG 族 "
|
|
707
|
+
"required 条目同族不同时点(配备建议 vs 登记/清理纪律),互引不合并;enforcement 轴"
|
|
708
|
+
"断言钉。",
|
|
709
|
+
],
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
# 新 id 域段(既有 catalog id 词面外;vocab-pr 登记诉求,照 materialize-curated 先例)
|
|
713
|
+
NEW_ID_SEGMENTS = {
|
|
714
|
+
"POLICY.CONTRACT.NO_INVENTED_FACTS": ["CONTRACT"],
|
|
715
|
+
"POLICY.GATE.RISK_FACTORS_CONFIRMED": ["GATE"],
|
|
716
|
+
"POLICY.BOUNDARY.VALIDATE_IN_ENCODE_OUT": ["BOUNDARY"],
|
|
717
|
+
"POLICY.DEP.BUILD_PATH_SUPPLY_CHAIN": [],
|
|
718
|
+
"POLICY.TOOL.NO_VENDORED_BODY_EDITS": [],
|
|
719
|
+
"POLICY.GUARD.NO_CHECK_WEAKENING": ["GUARD"],
|
|
720
|
+
"POLICY.SEC.NO_SECRETS_IN_CLIENT_SURFACE": [],
|
|
721
|
+
"POLICY.AI.FACT_INFERENCE_SEPARATION": ["AI"],
|
|
722
|
+
"POLICY.SEC.NO_LONGTERM_SECURITY_DISABLE": [],
|
|
723
|
+
"POLICY.REGISTRY.HUMAN_FIELDS_VALIDATED_DECORRELATED": ["REGISTRY"],
|
|
724
|
+
"POLICY.SEC.NO_SCRIPT_READABLE_CREDENTIALS": [],
|
|
725
|
+
"POLICY.GATE.P0_NON_BYPASSABLE": ["GATE"],
|
|
726
|
+
"POLICY.TEST.ISOLATION_AND_CLEANUP": ["TEST"],
|
|
727
|
+
"POLICY.SEC.AUTHN_POLICY_UNIFIED": [],
|
|
728
|
+
"POLICY.SEC.URL_SOURCE_ALLOWLIST": [],
|
|
729
|
+
"POLICY.AI.CHANGE_PLAN_FIRST": ["AI"],
|
|
730
|
+
"POLICY.ROLE.HUMAN_SIGNS_FOR_AI": [],
|
|
731
|
+
"POLICY.TEST.STABLE_OBSERVABLE_ASSERTIONS": ["TEST"],
|
|
732
|
+
"POLICY.PROC.SCOPE_DRIFT_RECLASSIFY": [],
|
|
733
|
+
"POLICY.SEC.UPLOAD_DOWNLOAD_SERVER_RECHECK": [],
|
|
734
|
+
"POLICY.CFG.PRODUCTION_SAFE_DEFAULTS": ["CFG"],
|
|
735
|
+
"POLICY.CFG.SCHEMA_BACKED_CONFIG": ["CFG"],
|
|
736
|
+
"POLICY.CHG.NO_UNRELATED_CHANGES": [],
|
|
737
|
+
"POLICY.TEST.PYRAMID_AND_CI_MATRIX": ["TEST"],
|
|
738
|
+
"POLICY.PROC.CHECKLIST_CHANGE_POLICY": [],
|
|
739
|
+
"POLICY.AI.RULE_RELAXATION_APPROVAL": ["AI"],
|
|
740
|
+
# ---- B6b-II(既有 catalog id 词面外的新域段;照 materialize-curated 先例待 vocab PR)----
|
|
741
|
+
"POLICY.FLAG.LIFECYCLE_METADATA": ["FLAG"],
|
|
742
|
+
"POLICY.OBS.NO_SENSITIVE_RAW_VALUES": [],
|
|
743
|
+
"POLICY.OBS.TELEMETRY_LIFECYCLE_DECLARED": [],
|
|
744
|
+
"POLICY.FLAG.CLEANUP_AFTER_FULL_ROLLOUT": ["FLAG"],
|
|
745
|
+
"POLICY.WEB.TRACK.NO_SYNTHETIC_ACTIONS": [],
|
|
746
|
+
"POLICY.FLAG.CONSISTENT_OFF_STATE": ["FLAG"],
|
|
747
|
+
"POLICY.OBS.CONTEXT_FIELD_BASELINE": [],
|
|
748
|
+
"POLICY.WEB.TRACK.ATTEMPT_RESULT_CORRELATION": [],
|
|
749
|
+
"POLICY.REL.TRACEABLE_BUILD": [],
|
|
750
|
+
"POLICY.WEB.I18N.RAW_VALUE_FOR_COMPUTE": ["I18N"],
|
|
751
|
+
"POLICY.FLAG.NOT_A_PERMISSION": ["FLAG"],
|
|
752
|
+
"POLICY.OBS.SOURCE_MAP_ACCESS_CONTROL": [],
|
|
753
|
+
"POLICY.OBS.ALERT_WITH_OWNER": [],
|
|
754
|
+
"POLICY.REL.OBSERVABILITY_BEFORE_SHIP": [],
|
|
755
|
+
"POLICY.WEB.COPY.ERROR_NEXT_STEP": [],
|
|
756
|
+
"POLICY.WEB.COPY.ACTION_OBJECT_CLARITY": [],
|
|
757
|
+
"POLICY.WEB.HANDOFF.STATE_MATRIX_FULL": ["HANDOFF"],
|
|
758
|
+
"POLICY.WEB.COPY.ENUMERABLE_PLACEMENT": [],
|
|
759
|
+
"POLICY.WEB.PAGE.REGION_CONSISTENCY": ["PAGE"],
|
|
760
|
+
"POLICY.WEB.COMP.PUBLIC_CONTRACT_COMPLETENESS": ["COMP"],
|
|
761
|
+
"POLICY.WEB.COMP.NO_TRIVIAL_OR_GOD_COMPONENT": ["COMP"],
|
|
762
|
+
"POLICY.WEB.I18N.COPY_KEY_DISCIPLINE": ["I18N"],
|
|
763
|
+
"POLICY.OBS.TRACE_CORRELATION": [],
|
|
764
|
+
"POLICY.WEB.TRACK.TYPED_CLIENT_VALIDATION": [],
|
|
765
|
+
"POLICY.FLAG.KILL_SWITCH": ["FLAG"],
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
# ======================================================================
|
|
770
|
+
# vendor 侧:12 段结构解析(段名→行区间)+ 正文 pin
|
|
771
|
+
# ======================================================================
|
|
772
|
+
SECTION_NAMES = ["Scope", "Non-Scope", "Terms", "MUST", "MUST NOT", "SHOULD",
|
|
773
|
+
"Contract", "Checklist", "Examples", "Anti-patterns", "Ownership",
|
|
774
|
+
"Change Policy"]
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
def parse_sections(raw_lines):
|
|
778
|
+
"""'## <段名>' 行号 → {段名: (start, end)}(1-based 闭区间,end=下一段前一行)。"""
|
|
779
|
+
marks = []
|
|
780
|
+
for i, line in enumerate(raw_lines, 1):
|
|
781
|
+
m = re.match(r"^## (.+?)\s*$", line)
|
|
782
|
+
if m:
|
|
783
|
+
marks.append((i, m.group(1)))
|
|
784
|
+
out = {}
|
|
785
|
+
for idx, (line_no, name) in enumerate(marks):
|
|
786
|
+
end = marks[idx + 1][0] - 1 if idx + 1 < len(marks) else len(raw_lines)
|
|
787
|
+
out[name] = (line_no, end)
|
|
788
|
+
return out
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
def sections_for_lines(sections, lines_str):
|
|
792
|
+
""""L23, L32" → 按行段映射去重后的段名数组(保序)。"""
|
|
793
|
+
names = []
|
|
794
|
+
for (a, b) in parse_line_anchors(lines_str):
|
|
795
|
+
for name, (s, e) in sections.items():
|
|
796
|
+
if s <= a <= e and name not in names:
|
|
797
|
+
names.append(name)
|
|
798
|
+
return names
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
# 12 段词形闭包(固定结构;MASTer 消费树的项目扩展段——如 10 文件的「本地 ESLint
|
|
802
|
+
# 规则与 Registry 校验」——不在闭包,锚落扩展段时不计入 enforcement 判定,单独
|
|
803
|
+
# 如实记录 extra_master_sections,分母不漂移)。
|
|
804
|
+
TWELVE_SECTION_NAMES = set(SECTION_NAMES)
|
|
805
|
+
|
|
806
|
+
_MASTER_SECTIONS_CACHE = {}
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
def master_anchor_sections(lines_str, protocol):
|
|
810
|
+
"""池卡行号锚(MASTer 分母)→ {twelve: [12 段内段名], extra: [项目扩展段名]}。"""
|
|
811
|
+
name = protocol.split("/")[-1]
|
|
812
|
+
if name not in _MASTER_SECTIONS_CACHE:
|
|
813
|
+
path = os.path.join(MASTER_DIR, name)
|
|
814
|
+
assert os.path.isfile(path), f"MASTer 源文件不存在: {protocol}"
|
|
815
|
+
raw_lines = open(path, encoding="utf-8").readlines()
|
|
816
|
+
_MASTER_SECTIONS_CACHE[name] = parse_sections(raw_lines)
|
|
817
|
+
all_names = sections_for_lines(_MASTER_SECTIONS_CACHE[name], lines_str)
|
|
818
|
+
twelve = [n for n in all_names if n in TWELVE_SECTION_NAMES]
|
|
819
|
+
extra = [n for n in all_names if n not in TWELVE_SECTION_NAMES]
|
|
820
|
+
return {"twelve": twelve, "extra": extra}
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
def parse_line_anchors(lines_str):
|
|
824
|
+
s = (lines_str or "").strip()
|
|
825
|
+
if not s:
|
|
826
|
+
return []
|
|
827
|
+
out = []
|
|
828
|
+
for m in re.finditer(r"[Ll](\d+)(?:\s*-\s*[Ll]?(\d+))?", s):
|
|
829
|
+
a = int(m.group(1))
|
|
830
|
+
b = int(m.group(2)) if m.group(2) else a
|
|
831
|
+
out.append((min(a, b), max(a, b)))
|
|
832
|
+
return out
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
def _norm_ws(s):
|
|
836
|
+
return re.sub(r"\s+", "", s)
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
def _lcs_len(a, b):
|
|
840
|
+
if not a or not b:
|
|
841
|
+
return 0
|
|
842
|
+
prev = [0] * (len(b) + 1)
|
|
843
|
+
best = 0
|
|
844
|
+
for i in range(1, len(a) + 1):
|
|
845
|
+
cur = [0] * (len(b) + 1)
|
|
846
|
+
ca = a[i - 1]
|
|
847
|
+
for j in range(1, len(b) + 1):
|
|
848
|
+
if ca == b[j - 1]:
|
|
849
|
+
cur[j] = prev[j - 1] + 1
|
|
850
|
+
if cur[j] > best:
|
|
851
|
+
best = cur[j]
|
|
852
|
+
prev = cur
|
|
853
|
+
return best
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
# ======================================================================
|
|
857
|
+
# 播种资产构建(frontmatter + vendor 正文逐字节;index.md 唯一授权词形适配点)
|
|
858
|
+
# ======================================================================
|
|
859
|
+
def build_frontmatter(source_rel, sha_hex, seed_version):
|
|
860
|
+
lines = [
|
|
861
|
+
"---",
|
|
862
|
+
f"seed_source: {source_rel}",
|
|
863
|
+
f"seed_source_sha256: {sha_hex}",
|
|
864
|
+
f"seed_version: {seed_version}",
|
|
865
|
+
f"lane: {LANE}",
|
|
866
|
+
"status: CURRENT",
|
|
867
|
+
f"authority_scope: {AUTHORITY_SCOPE}",
|
|
868
|
+
f"applies_to: [{LANE}]",
|
|
869
|
+
"related_evidence_specs: []",
|
|
870
|
+
"related_tools: []",
|
|
871
|
+
"---",
|
|
872
|
+
"",
|
|
873
|
+
]
|
|
874
|
+
return ("\n".join(lines) + "\n").encode("utf-8")
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
def vendor_file_for(num_or_index):
|
|
878
|
+
"""批分母项('01'..'45'/'index')→ vendor 文件名(分母漂移即爆)。"""
|
|
879
|
+
if num_or_index == "index":
|
|
880
|
+
name = INDEX_NAME
|
|
881
|
+
assert os.path.isfile(os.path.join(VENDOR_DIR, name)), "vendor index.md 缺席"
|
|
882
|
+
return name
|
|
883
|
+
names = [n for n in os.listdir(VENDOR_DIR)
|
|
884
|
+
if n.startswith(num_or_index + "-") and n.endswith(".md")]
|
|
885
|
+
assert len(names) == 1, f"vendor 分母漂移({num_or_index}-* 命中 {names})"
|
|
886
|
+
return names[0]
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
def apply_r8_cleanups(body, cleanlines):
|
|
890
|
+
"""R8 清洗(裁决 12/D5 授权内容演进批次,2026-09-05):整行替换 + 逐条计数断言
|
|
891
|
+
(vendor 漂移即爆,禁静默零替换);最小改写——未列词形/行零触碰。"""
|
|
892
|
+
for old, new, expect_count in cleanlines:
|
|
893
|
+
old_b, new_b = old.encode("utf-8"), new.encode("utf-8")
|
|
894
|
+
found = body.count(old_b)
|
|
895
|
+
assert found == expect_count, (
|
|
896
|
+
f"R8 清洗锚点计数漂移:{old[:36]!r}… 预期 {expect_count} 处,实测 {found} 处")
|
|
897
|
+
body = body.replace(old_b, new_b)
|
|
898
|
+
return body
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
def seed_body_for(vendor_bytes, name, source_rel, sha_hex, seed_version):
|
|
902
|
+
"""frontmatter + 正文;编号协议正文逐字节 == vendor(01/03 除外——R8 清洗整行
|
|
903
|
+
替换恰等,裁决 12/D5);index.md 施加 whitelist 词形适配(逐条计数断言,漂移
|
|
904
|
+
即爆)。"""
|
|
905
|
+
fm = build_frontmatter(source_rel, sha_hex, seed_version)
|
|
906
|
+
if name == INDEX_NAME:
|
|
907
|
+
adapted = vendor_bytes
|
|
908
|
+
for old, new, expect_count in INDEX_ADAPTATIONS:
|
|
909
|
+
old_b, new_b = old.encode("utf-8"), new.encode("utf-8")
|
|
910
|
+
found = adapted.count(old_b)
|
|
911
|
+
assert found == expect_count, (
|
|
912
|
+
f"index.md 适配点计数漂移:{old!r} 预期 {expect_count} 处,实测 {found} 处")
|
|
913
|
+
adapted = adapted.replace(old_b, new_b)
|
|
914
|
+
adapted = apply_r8_cleanups(adapted, INDEX_R8_CLEANLINES)
|
|
915
|
+
assert adapted != vendor_bytes, "index.md 适配未生效(授权适配点必须落地)"
|
|
916
|
+
return fm + adapted
|
|
917
|
+
cleanlines = R8_CLEANLINES.get(name)
|
|
918
|
+
if cleanlines:
|
|
919
|
+
return fm + apply_r8_cleanups(vendor_bytes, cleanlines)
|
|
920
|
+
body = fm + vendor_bytes
|
|
921
|
+
# A4/内容忠实断言:去 frontmatter 后正文与 vendor 逐字节相等(构建两遍同构)。
|
|
922
|
+
assert body[len(fm):] == vendor_bytes
|
|
923
|
+
return body
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
def build_seed_assets():
|
|
927
|
+
"""46 份播种件字节 + 清单(两批合并分母)。返回 (assets, manifest_doc)。"""
|
|
928
|
+
assets = {}
|
|
929
|
+
entries = []
|
|
930
|
+
batch_targets = {}
|
|
931
|
+
for batch, nums in BATCHES.items():
|
|
932
|
+
targets = []
|
|
933
|
+
for num in nums:
|
|
934
|
+
name = vendor_file_for(num)
|
|
935
|
+
vendor_bytes = open(os.path.join(VENDOR_DIR, name), "rb").read()
|
|
936
|
+
sha_hex = hashlib.sha256(vendor_bytes).hexdigest()
|
|
937
|
+
if name in PILOT_VENDOR_SHA:
|
|
938
|
+
# R1 pin 全等对账(B6b-II 收紧——截断回退已移除,取材分母漂移即爆)。
|
|
939
|
+
assert sha_hex == PILOT_VENDOR_SHA[name], (
|
|
940
|
+
f"R1 pin 对账失败:{name} vendor sha 与 pilot_verification 钉死值不符 "
|
|
941
|
+
f"(取材分母漂移?): {sha_hex} vs {PILOT_VENDOR_SHA[name]}")
|
|
942
|
+
source_rel = f"pomaster/components/frontend-hard-spec/assets/universal/{name}"
|
|
943
|
+
body = seed_body_for(vendor_bytes, name, source_rel, sha_hex, batch)
|
|
944
|
+
rel = f"specs/hard/frontend/{name}"
|
|
945
|
+
assets[rel] = body
|
|
946
|
+
targets.append(f".pomaster/{rel}")
|
|
947
|
+
entries.append({
|
|
948
|
+
"target": f".pomaster/{rel}",
|
|
949
|
+
"asset": rel,
|
|
950
|
+
"seed_version": batch,
|
|
951
|
+
"lane": LANE,
|
|
952
|
+
"source_path": source_rel,
|
|
953
|
+
"source_sha256": sha_hex,
|
|
954
|
+
"source_bytes": len(vendor_bytes),
|
|
955
|
+
"porting_notes": list(PORTING_NOTES.get(name, [])),
|
|
956
|
+
})
|
|
957
|
+
batch_targets[batch] = targets
|
|
958
|
+
# manifest(merge_preserving——裁定批 F 工具-目录漂移修复 ADR:磁盘清单自 B6c 起
|
|
959
|
+
# 为多批合并单源(B6b 两批 + B6c/B6d/B6e 追加),本工具重演只重算 B6b 两批名单与
|
|
960
|
+
# 条目;其余批的批次名单、条目与磁盘头部字段(batch/generated_by/denominator/
|
|
961
|
+
# seed_semantics/authority_scope)**原样保留**——纯重建形态会覆写后续批追加内容
|
|
962
|
+
# (批 B resolution 转正与 B6d/B6e 清单追加曾同因漂移),merge_preserving 同类
|
|
963
|
+
# 语义收口;本批重算与磁盘逐字差异由 --verify 字节比对如实暴露)。
|
|
964
|
+
old_doc = json.loads(open(MANIFEST_PATH, encoding="utf-8").read())
|
|
965
|
+
assert old_doc["schema"] == MANIFEST_SCHEMA
|
|
966
|
+
old_entries = old_doc["entries"]
|
|
967
|
+
old_batches = old_doc.get("batches") or {}
|
|
968
|
+
assert set(BATCHES) <= set(old_batches), "磁盘清单缺 B6b 两批名单"
|
|
969
|
+
# 原位替换(磁盘键序/条目序恒保持——merge 收敛性:B6b/B6c 交替重演不漂移)。
|
|
970
|
+
by_target = {e["target"]: e for e in entries}
|
|
971
|
+
merged_entries = []
|
|
972
|
+
seen = set()
|
|
973
|
+
for e in old_entries:
|
|
974
|
+
if e["target"] in by_target:
|
|
975
|
+
merged_entries.append(by_target[e["target"]])
|
|
976
|
+
seen.add(e["target"])
|
|
977
|
+
else:
|
|
978
|
+
merged_entries.append(e)
|
|
979
|
+
missing = set(by_target) - seen
|
|
980
|
+
assert not missing, f"本批条目在磁盘清单缺席(名单漂移): {sorted(missing)}"
|
|
981
|
+
merged_batches = {}
|
|
982
|
+
for k, v in old_batches.items():
|
|
983
|
+
merged_batches[k] = list(batch_targets[k]) if k in BATCHES else list(v)
|
|
984
|
+
manifest_doc = dict(old_doc)
|
|
985
|
+
manifest_doc["batches"] = merged_batches
|
|
986
|
+
manifest_doc["entries"] = merged_entries
|
|
987
|
+
assert len(manifest_doc["entries"]) == old_doc["denominator"]["planted"], \
|
|
988
|
+
"manifest 合并分母与磁盘 denominator.planted 漂移"
|
|
989
|
+
return assets, manifest_doc
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
# ======================================================================
|
|
993
|
+
# 池选取(required 22 + advisory 3)
|
|
994
|
+
# ======================================================================
|
|
995
|
+
def load_raw_cards():
|
|
996
|
+
cards = {}
|
|
997
|
+
|
|
998
|
+
def walk(node, out):
|
|
999
|
+
if isinstance(node, dict):
|
|
1000
|
+
if "proposed_id" in node:
|
|
1001
|
+
out.append(node)
|
|
1002
|
+
return
|
|
1003
|
+
for v in node.values():
|
|
1004
|
+
walk(v, out)
|
|
1005
|
+
elif isinstance(node, list):
|
|
1006
|
+
for v in node:
|
|
1007
|
+
walk(v, out)
|
|
1008
|
+
|
|
1009
|
+
for group in GROUPS:
|
|
1010
|
+
path = os.path.join(CAND_DIR, group + ".yaml")
|
|
1011
|
+
doc = yaml.safe_load(open(path, encoding="utf-8"))
|
|
1012
|
+
files = doc if isinstance(doc, list) else doc.get("files", [])
|
|
1013
|
+
found = []
|
|
1014
|
+
walk(doc, found)
|
|
1015
|
+
for c in found:
|
|
1016
|
+
cid = c.get("proposed_id")
|
|
1017
|
+
if cid:
|
|
1018
|
+
assert cid not in cards, f"跨组 id 撞名: {cid}"
|
|
1019
|
+
cards[cid] = {"group": group, "raw": c}
|
|
1020
|
+
return cards
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
def vendor_path_for(protocol):
|
|
1024
|
+
""".trellis/spec/frontend/XX-*.md(MASTer 分母路径)→ vendor 同名文件路径。"""
|
|
1025
|
+
name = protocol.split("/")[-1]
|
|
1026
|
+
return os.path.join(VENDOR_DIR, name), name
|
|
1027
|
+
|
|
1028
|
+
|
|
1029
|
+
def density(stmt, lane):
|
|
1030
|
+
s = _norm_ws(stmt)
|
|
1031
|
+
cardinals = len(re.findall(r"[一二三四五六七八九十0-9]+\s*(项|件|类|条|元|要素|成分|维度|件事)", s))
|
|
1032
|
+
score = min(len(s), 160) / 16.0
|
|
1033
|
+
score += 8.0 * cardinals
|
|
1034
|
+
score += 30.0 if lane == "any" else 0.0
|
|
1035
|
+
return round(score, 2)
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
def select_curated(pool, raw):
|
|
1039
|
+
ranked = pool["eligible_ranked"]
|
|
1040
|
+
ident = pool["identity"]
|
|
1041
|
+
assert ident["total_candidates"] == EXPECT_TOTAL, "池候选总数漂移"
|
|
1042
|
+
assert ident["canonical_total"] == EXPECT_CANONICAL, "池正本数漂移"
|
|
1043
|
+
assert ident["absorbed_total"] == EXPECT_ABSORBED, "池 absorbed 数漂移"
|
|
1044
|
+
assert pool["d5_screen_summary"]["eligible_pool"] == EXPECT_ELIGIBLE, "ELIGIBLE 池漂移"
|
|
1045
|
+
|
|
1046
|
+
# 磁盘 catalog 分桶(幂等重演语义):
|
|
1047
|
+
# - existing_b6:x-b6-porting.batch == 本批 的条目——重演时**原位收编**(扫描中
|
|
1048
|
+
# 直接占位,不参与排除/补位),保证重演名单与首次构建逐 id 一致;
|
|
1049
|
+
# - materialized:其余 x-spec-d-materialization 在场条目——池排除(本批之前
|
|
1050
|
+
# 已物化的卡不再入选)。
|
|
1051
|
+
existing_b6 = {}
|
|
1052
|
+
materialized = set()
|
|
1053
|
+
for section in ("policies", "knowledge", "gates", "sensors", "archetypes"):
|
|
1054
|
+
sdir = os.path.join(VNEXT, "catalog", section)
|
|
1055
|
+
if not os.path.isdir(sdir):
|
|
1056
|
+
continue
|
|
1057
|
+
for fn in os.listdir(sdir):
|
|
1058
|
+
if not fn.endswith(".json"):
|
|
1059
|
+
continue
|
|
1060
|
+
try:
|
|
1061
|
+
d = json.load(open(os.path.join(sdir, fn), encoding="utf-8"))
|
|
1062
|
+
except Exception:
|
|
1063
|
+
continue
|
|
1064
|
+
if not isinstance(d, dict):
|
|
1065
|
+
continue
|
|
1066
|
+
note = d.get("x-b6-porting")
|
|
1067
|
+
if isinstance(note, dict) and note.get("batch") == BATCH:
|
|
1068
|
+
existing_b6[d["id"]] = d.get("enforcement")
|
|
1069
|
+
continue
|
|
1070
|
+
m = d.get("x-spec-d-materialization")
|
|
1071
|
+
if isinstance(m, dict) and m.get("candidate_id"):
|
|
1072
|
+
materialized.add(m["candidate_id"])
|
|
1073
|
+
|
|
1074
|
+
fe2_rows = [r for r in ranked
|
|
1075
|
+
if r["source_protocol"].startswith(FE2_DENOM_PREFIXES)
|
|
1076
|
+
or r["source_protocol"] == INDEX_PROTOCOL]
|
|
1077
|
+
|
|
1078
|
+
# required 池:ELIGIBLE 未物化 + 行锚段验证(MASTer 分母逐卡核锚)按池序取前 22。
|
|
1079
|
+
# 矛盾排除:池 enforcement=required 但行锚不落 MUST/MUST NOT 段(如 Change Policy
|
|
1080
|
+
# 源 / index.md 卡天然无 12 段锚)的卡保守排除——不猜 Owner 意图,留池待复核
|
|
1081
|
+
# (强度只降不升;矛盾入选 = 以 required 强度为源段背书,超出了锚证据)。
|
|
1082
|
+
required = []
|
|
1083
|
+
excluded = []
|
|
1084
|
+
for r in fe2_rows:
|
|
1085
|
+
cid = r["candidate_id"]
|
|
1086
|
+
if len(required) >= REQUIRED_CAP:
|
|
1087
|
+
break
|
|
1088
|
+
if cid in existing_b6:
|
|
1089
|
+
if existing_b6[cid] == "required_when_applicable":
|
|
1090
|
+
required.append(r)
|
|
1091
|
+
continue
|
|
1092
|
+
if cid in materialized:
|
|
1093
|
+
continue
|
|
1094
|
+
raw_card = raw.get(cid, {}).get("raw", {})
|
|
1095
|
+
anchors = master_anchor_sections(str(raw_card.get("source_lines") or ""),
|
|
1096
|
+
r["source_protocol"])
|
|
1097
|
+
if not any(s in ("MUST", "MUST NOT") for s in anchors["twelve"]):
|
|
1098
|
+
reason = (
|
|
1099
|
+
"行锚全落 MASTer 项目扩展段(12 段闭包外),无源强度证据,保守排除待复核"
|
|
1100
|
+
if not anchors["twelve"] else
|
|
1101
|
+
"行锚段映射非 MUST/MUST NOT(池 enforcement 判定矛盾,保守排除待复核)"
|
|
1102
|
+
)
|
|
1103
|
+
excluded.append({"pool": "required", "candidate_id": cid, "reason": reason,
|
|
1104
|
+
"sections": anchors["twelve"], "extra": anchors["extra"]})
|
|
1105
|
+
continue
|
|
1106
|
+
required.append(r)
|
|
1107
|
+
assert len(required) == REQUIRED_CAP, f"required 池不足: {len(required)}"
|
|
1108
|
+
|
|
1109
|
+
# advisory 池:SHOULD 源 canonical_backlog policy 卡按同公式密度序取前 3。
|
|
1110
|
+
# existing 本批卡**无条件收编**(重演名单锁定);challenger 仅当收编数不足
|
|
1111
|
+
# ADVISORY_CAP 时参与排序补位(防重演漂移)。B6b-II 收紧:challenger 先过锚证据
|
|
1112
|
+
# 预筛——无 12 段锚(index.md 卡)或锚段不全落建议段闭包(如 Ownership 源卡)的
|
|
1113
|
+
# 保守排除留池待复核(与 required 池同法:池判定与锚证据矛盾时不猜 Owner 意图)。
|
|
1114
|
+
existing_adv_count = sum(
|
|
1115
|
+
1 for cid in existing_b6 if existing_b6[cid] == "advisory"
|
|
1116
|
+
)
|
|
1117
|
+
adv_rows = []
|
|
1118
|
+
for r in pool["canonical_backlog"]:
|
|
1119
|
+
sp = r.get("source_protocol", "")
|
|
1120
|
+
if not (sp.startswith(FE2_DENOM_PREFIXES) or sp == INDEX_PROTOCOL):
|
|
1121
|
+
continue
|
|
1122
|
+
if r.get("enforcement") != "advisory" or r.get("kind") != "policy":
|
|
1123
|
+
continue
|
|
1124
|
+
cid = r["candidate_id"]
|
|
1125
|
+
if cid in existing_b6:
|
|
1126
|
+
if existing_b6[cid] == "advisory":
|
|
1127
|
+
raw_card = raw.get(cid, {}).get("raw", {})
|
|
1128
|
+
stmt = raw_card.get("statement_zh", "")
|
|
1129
|
+
adv_rows.append(dict(r, _density=density(stmt, r.get("applies_lane", "any"))))
|
|
1130
|
+
continue
|
|
1131
|
+
if cid in materialized:
|
|
1132
|
+
continue
|
|
1133
|
+
if existing_adv_count >= ADVISORY_CAP:
|
|
1134
|
+
continue
|
|
1135
|
+
raw_card = raw.get(cid, {}).get("raw", {})
|
|
1136
|
+
stmt = raw_card.get("statement_zh", "")
|
|
1137
|
+
assert stmt, f"advisory 卡缺 statement: {cid}"
|
|
1138
|
+
anchors = master_anchor_sections(str(raw_card.get("source_lines") or ""),
|
|
1139
|
+
r["source_protocol"])
|
|
1140
|
+
if not anchors["twelve"]:
|
|
1141
|
+
excluded.append({
|
|
1142
|
+
"pool": "advisory", "candidate_id": cid,
|
|
1143
|
+
"reason": "行锚全落 MASTer 项目扩展段(12 段闭包外),无源段证据,保守排除待复核",
|
|
1144
|
+
"sections": anchors["twelve"], "extra": anchors["extra"]})
|
|
1145
|
+
continue
|
|
1146
|
+
if not all(s in ("SHOULD", "Change Policy") for s in anchors["twelve"]):
|
|
1147
|
+
excluded.append({
|
|
1148
|
+
"pool": "advisory", "candidate_id": cid,
|
|
1149
|
+
"reason": "行锚段映射非纯建议段(池 advisory 判定矛盾,保守排除待复核)",
|
|
1150
|
+
"sections": anchors["twelve"], "extra": anchors["extra"]})
|
|
1151
|
+
continue
|
|
1152
|
+
rec = dict(r, _density=density(stmt, r.get("applies_lane", "any")))
|
|
1153
|
+
adv_rows.append(rec)
|
|
1154
|
+
adv_rows.sort(key=lambda x: (-x["_density"], GROUPS.index(x["group"]), x["candidate_id"]))
|
|
1155
|
+
advisory = adv_rows[:ADVISORY_CAP]
|
|
1156
|
+
|
|
1157
|
+
ids = [r["candidate_id"] for r in required] + [r["candidate_id"] for r in advisory]
|
|
1158
|
+
assert len(set(ids)) == CURATED_CAP, "精选集 id 重复"
|
|
1159
|
+
return required, advisory, excluded
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
def clean_room_audit_vendor(cid, statement, protocol, anchors):
|
|
1163
|
+
"""LCS 审计(MASTer 侧行段——池卡行号锚的分母;阈值 20 字 fail-closed)。"""
|
|
1164
|
+
path = os.path.join(MASTER_DIR, protocol.split("/")[-1])
|
|
1165
|
+
assert os.path.isfile(path), f"MASTer 源文件不存在: {protocol} ({cid})"
|
|
1166
|
+
raw_lines = open(path, encoding="utf-8").readlines()
|
|
1167
|
+
segs = []
|
|
1168
|
+
for (a, b) in anchors:
|
|
1169
|
+
a = max(a, 1)
|
|
1170
|
+
b = min(b, len(raw_lines))
|
|
1171
|
+
if a <= b:
|
|
1172
|
+
segs.append("".join(raw_lines[a - 1:b]))
|
|
1173
|
+
ref_text = _norm_ws("".join(segs))
|
|
1174
|
+
stmt = _norm_ws(statement)
|
|
1175
|
+
worst = _lcs_len(stmt, ref_text) if ref_text else 0
|
|
1176
|
+
assert worst < LCS_THRESHOLD, f"clean-room LCS 审计失败({worst}>=20 字): {cid}"
|
|
1177
|
+
return worst
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
# ======================================================================
|
|
1181
|
+
# catalog 条目构建(materialize-curated 同款模式 + x-b6-porting 注记)
|
|
1182
|
+
# ======================================================================
|
|
1183
|
+
def id_to_path(cid):
|
|
1184
|
+
return "policies/" + cid.lower() + ".json"
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
BATCH_LABEL = {"B6B-1": "B6b-I", "B6B-2": "B6b-II"}[BATCH]
|
|
1188
|
+
CURATED_RULE = (
|
|
1189
|
+
f"{BATCH_LABEL} 分母(FE 24-45 + index)required 池(ELIGIBLE 未物化 + MASTer 行锚"
|
|
1190
|
+
"落 MUST/MUST NOT)按池密度序取前 22 + advisory 池(SHOULD 源 backlog policy 卡 + "
|
|
1191
|
+
"锚段全落建议段闭包)按同公式密度序取前 3 = 25(D5 上限/批内执行);UNIVERSAL + "
|
|
1192
|
+
"UNIVERSAL_POLICY + 无 uncertainty + 非 project_scope + 非重复"
|
|
1193
|
+
)
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
def build_entry(pool_rec, card, statement, sections, sha_hex, vendor_bytes, seeded_target,
|
|
1197
|
+
extra_sections):
|
|
1198
|
+
cid = pool_rec["candidate_id"]
|
|
1199
|
+
group = card["group"]
|
|
1200
|
+
r = card["raw"]
|
|
1201
|
+
protocol = r["source_protocol"]
|
|
1202
|
+
lines = str(r.get("source_lines") or "")
|
|
1203
|
+
_, vendor_name = vendor_path_for(protocol)
|
|
1204
|
+
vendor_rel = f"pomaster/components/frontend-hard-spec/assets/universal/{vendor_name}"
|
|
1205
|
+
locator = {
|
|
1206
|
+
"candidate": cid,
|
|
1207
|
+
"source_protocol": protocol,
|
|
1208
|
+
"lines": lines,
|
|
1209
|
+
}
|
|
1210
|
+
new_segments = NEW_ID_SEGMENTS[cid]
|
|
1211
|
+
seg_note = (";新 id 域段待登记:" + "/".join(new_segments)) if new_segments else ""
|
|
1212
|
+
condition = (r.get("applies_when") or {}).get("condition", "")
|
|
1213
|
+
lane = (r.get("applies_when") or {}).get("lane", "any")
|
|
1214
|
+
entry = {
|
|
1215
|
+
"x-vocab-pr": {
|
|
1216
|
+
"status": "vocab_pr_candidate",
|
|
1217
|
+
"finding": "kind='policy' 不在 vocab-lock kinds_registry.truth_bodies(POLICY. 前缀已冻结注册,closed-world)" + seg_note,
|
|
1218
|
+
"proposal": "词汇表 PR 登记 policy kind 及新域段;或 Owner 裁决 policy 条目住 catalog/ 而非 truth/objects 正文层(与前批 45+25 条同因同请,合并进同一 vocab PR)",
|
|
1219
|
+
"locked_vocab_untouched": True,
|
|
1220
|
+
"resolution": VOCAB_PR_RESOLUTION_POLICY,
|
|
1221
|
+
},
|
|
1222
|
+
"x-spec-d-materialization": {
|
|
1223
|
+
"status": "PROPOSAL",
|
|
1224
|
+
"package": f"{BATCH_LABEL} FE 播种移植(SPEC-D 池卡复用;分母=MASTer 池卡 + "
|
|
1225
|
+
"vendor 播种字节双锚)",
|
|
1226
|
+
"human_review_required": True,
|
|
1227
|
+
"evidence": "PLANNED",
|
|
1228
|
+
"provenance": POOL_REL,
|
|
1229
|
+
"group": group,
|
|
1230
|
+
"candidate_id": cid,
|
|
1231
|
+
"density_rank": pool_rec.get("density_rank"),
|
|
1232
|
+
"density_score": pool_rec.get("density_score") or pool_rec.get("_density"),
|
|
1233
|
+
"pool_statement_sha16": pool_rec.get("statement_sha16"),
|
|
1234
|
+
"curated_rule": CURATED_RULE,
|
|
1235
|
+
"denominator": "MASTer(池卡 source_protocol 锚)",
|
|
1236
|
+
},
|
|
1237
|
+
"x-b6-porting": {
|
|
1238
|
+
"status": "PROPOSAL",
|
|
1239
|
+
"batch": BATCH,
|
|
1240
|
+
"human_review_required": True,
|
|
1241
|
+
"enforcement_axis": {
|
|
1242
|
+
"source_sections": sections,
|
|
1243
|
+
"rule": "SHOULD/Change Policy 源条目 enforcement 必须 advisory(禁升 required);"
|
|
1244
|
+
"MUST/MUST NOT 源条目 enforcement 必须 required_when_applicable(降级合法)",
|
|
1245
|
+
"asserted_by": "packages/cli/tests/catalog-b6-porting.spec.ts",
|
|
1246
|
+
},
|
|
1247
|
+
# MASTer 消费树的项目扩展段锚(12 段闭包外;无源强度语义,不计入
|
|
1248
|
+
# enforcement 判定——分母如实标注,R1 双分母注记的延伸)。
|
|
1249
|
+
"extra_master_sections": extra_sections,
|
|
1250
|
+
"denominator": "vendor",
|
|
1251
|
+
"vendor_pin": {
|
|
1252
|
+
"path": vendor_rel,
|
|
1253
|
+
"sha256": sha_hex,
|
|
1254
|
+
"bytes": vendor_bytes,
|
|
1255
|
+
},
|
|
1256
|
+
"seeded_spec": seeded_target,
|
|
1257
|
+
"seed_manifest": "packages/cli/seeds/manifest.json",
|
|
1258
|
+
},
|
|
1259
|
+
"id": cid,
|
|
1260
|
+
"kind": "policy",
|
|
1261
|
+
"axis_profile": "policy_default",
|
|
1262
|
+
"classification": "UNIVERSAL_POLICY",
|
|
1263
|
+
"axes": {
|
|
1264
|
+
"lifecycle": "PROPOSED",
|
|
1265
|
+
"confidence": "UNRESOLVED",
|
|
1266
|
+
"evidence": "PLANNED",
|
|
1267
|
+
"change": "STABLE",
|
|
1268
|
+
},
|
|
1269
|
+
"title_zh": TITLES[cid],
|
|
1270
|
+
"statement_zh": statement,
|
|
1271
|
+
"statement_en_keywords": list(KEYWORDS[cid]),
|
|
1272
|
+
"applies_when": {
|
|
1273
|
+
"lane": lane,
|
|
1274
|
+
"condition": condition,
|
|
1275
|
+
"applicability_note": condition,
|
|
1276
|
+
},
|
|
1277
|
+
"enforcement": pool_rec["enforcement"],
|
|
1278
|
+
"authority": {
|
|
1279
|
+
"owner": "HUMAN_OWNER",
|
|
1280
|
+
"delegates": [],
|
|
1281
|
+
"write_policy": "EVOLUTION_CHANNEL",
|
|
1282
|
+
"escalation_hint": "catalog-spec-decomposition",
|
|
1283
|
+
},
|
|
1284
|
+
"origin": "ingested",
|
|
1285
|
+
"origin_note": (
|
|
1286
|
+
f"{BATCH_LABEL} FE 播种移植物化;statement 在物化层以独立措辞改写(clean-room;源卡语句"
|
|
1287
|
+
"与上游存在逐字重合,已消除),零逐字拷贝上游源文本;播种分母=vendor 字节"
|
|
1288
|
+
"(x-b6-porting.vendor_pin),分解分母=MASTer 池卡(x-spec-d-materialization)"
|
|
1289
|
+
) if cid in REWRITE_TEXT else (
|
|
1290
|
+
f"{BATCH_LABEL} FE 播种移植物化;statement 沿用 SPEC-D 候选卡独立措辞(clean-room),"
|
|
1291
|
+
"零逐字拷贝上游源文本;播种分母=vendor 字节(x-b6-porting.vendor_pin),"
|
|
1292
|
+
"分解分母=MASTer 池卡(x-spec-d-materialization)"
|
|
1293
|
+
),
|
|
1294
|
+
"sources": [
|
|
1295
|
+
{
|
|
1296
|
+
"type": "design_seed",
|
|
1297
|
+
"ref": "POMaster_VNext/corpus/spec-knowledge/candidates/%s.yaml" % group,
|
|
1298
|
+
"captured_by": "agent:claude/spec-d-consolidation",
|
|
1299
|
+
"locator": locator,
|
|
1300
|
+
"clean_room_note": CLEAN_ROOM_NOTE,
|
|
1301
|
+
}
|
|
1302
|
+
],
|
|
1303
|
+
"review_notes": list(REVIEW_NOTES[cid]),
|
|
1304
|
+
}
|
|
1305
|
+
if cid in REWRITE_TEXT:
|
|
1306
|
+
entry["x-spec-d-materialization"]["clean_room_rewrite"] = True
|
|
1307
|
+
return entry
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
def serialize(obj):
|
|
1311
|
+
return json.dumps(obj, ensure_ascii=False, indent=2) + "\n"
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
def write_if_changed(path, data):
|
|
1315
|
+
if os.path.isfile(path):
|
|
1316
|
+
if open(path, "rb").read() == data:
|
|
1317
|
+
return False
|
|
1318
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
1319
|
+
open(path, "wb").write(data)
|
|
1320
|
+
return True
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
# ======================================================================
|
|
1324
|
+
# 主流程
|
|
1325
|
+
# ======================================================================
|
|
1326
|
+
def build_all():
|
|
1327
|
+
assets, manifest_doc = build_seed_assets()
|
|
1328
|
+
pool = yaml.safe_load(open(POOL_PATH, encoding="utf-8"))
|
|
1329
|
+
raw = load_raw_cards()
|
|
1330
|
+
required, advisory, excluded = select_curated(pool, raw)
|
|
1331
|
+
|
|
1332
|
+
entry_bytes = {}
|
|
1333
|
+
audits = []
|
|
1334
|
+
for rec in required + advisory:
|
|
1335
|
+
cid = rec["candidate_id"]
|
|
1336
|
+
card = raw[cid]
|
|
1337
|
+
r = card["raw"]
|
|
1338
|
+
if cid in REWRITE_TEXT:
|
|
1339
|
+
statement = REWRITE_TEXT[cid]
|
|
1340
|
+
else:
|
|
1341
|
+
statement = r["statement_zh"]
|
|
1342
|
+
pool_stmt = rec.get("statement_zh")
|
|
1343
|
+
# eligible_ranked 带池 statement;canonical_backlog 卡不带(键集更短)——
|
|
1344
|
+
# 在场才比对。
|
|
1345
|
+
if pool_stmt is not None:
|
|
1346
|
+
assert _norm_ws(statement) == _norm_ws(pool_stmt), \
|
|
1347
|
+
f"卡 statement 与池不一致: {cid}"
|
|
1348
|
+
assert statement and statement.strip(), f"卡缺 statement: {cid}"
|
|
1349
|
+
protocol = r["source_protocol"]
|
|
1350
|
+
anchors = master_anchor_sections(str(r.get("source_lines") or ""), protocol)
|
|
1351
|
+
sections = anchors["twelve"]
|
|
1352
|
+
assert sections, f"行段无法映射到 12 段: {cid} ({r.get('source_lines')})"
|
|
1353
|
+
# enforcement 轴(工具级自我断言——物化前先自证,测试面二次钉):
|
|
1354
|
+
# 主锚语义——多锚卡(MUST/MUST NOT 锚 + SHOULD 锚同事实)按最强段定强度
|
|
1355
|
+
# (有 MUST/MUST NOT 锚 → required);全部锚均建议段(SHOULD/Change Policy)
|
|
1356
|
+
# → advisory。纯建议段卡禁升 required(MUST 通胀守卫的核心语义)。
|
|
1357
|
+
adv_ok = all(s in ("SHOULD", "Change Policy") for s in sections)
|
|
1358
|
+
assert (rec["enforcement"] == "advisory") == adv_ok, (
|
|
1359
|
+
f"enforcement 轴映射违例: {cid} sections={sections} enforcement={rec['enforcement']}")
|
|
1360
|
+
worst = clean_room_audit_vendor(cid, statement, protocol,
|
|
1361
|
+
parse_line_anchors(str(r.get("source_lines") or "")))
|
|
1362
|
+
audits.append({"id": cid, "lcs_max": worst, "sections": sections})
|
|
1363
|
+
vendor_path, vendor_name = vendor_path_for(protocol)
|
|
1364
|
+
vendor_bytes = open(vendor_path, "rb").read()
|
|
1365
|
+
sha_hex = hashlib.sha256(vendor_bytes).hexdigest()
|
|
1366
|
+
entry = build_entry(rec, card, statement, sections, sha_hex, len(vendor_bytes),
|
|
1367
|
+
f".pomaster/specs/hard/frontend/{vendor_name}",
|
|
1368
|
+
anchors["extra"])
|
|
1369
|
+
rel = id_to_path(cid)
|
|
1370
|
+
entry_bytes[rel] = serialize(entry).encode("utf-8")
|
|
1371
|
+
|
|
1372
|
+
return {
|
|
1373
|
+
"assets": assets,
|
|
1374
|
+
"manifest": manifest_doc,
|
|
1375
|
+
"entry_bytes": entry_bytes,
|
|
1376
|
+
"audits": audits,
|
|
1377
|
+
"counts": {"required": len(required), "advisory": len(advisory)},
|
|
1378
|
+
"excluded": excluded,
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
|
|
1382
|
+
def main():
|
|
1383
|
+
built = build_all()
|
|
1384
|
+
outputs = {}
|
|
1385
|
+
for rel, data in built["assets"].items():
|
|
1386
|
+
outputs[os.path.join(ASSET_DIR, *rel.split("/")[3:])] = data
|
|
1387
|
+
outputs[MANIFEST_PATH] = serialize(built["manifest"]).encode("utf-8")
|
|
1388
|
+
for rel, data in built["entry_bytes"].items():
|
|
1389
|
+
outputs[os.path.join(POLICY_DIR, *rel.split("/")[1:])] = data
|
|
1390
|
+
|
|
1391
|
+
if "--verify" in sys.argv:
|
|
1392
|
+
drifts = []
|
|
1393
|
+
for path, data in outputs.items():
|
|
1394
|
+
if not os.path.isfile(path):
|
|
1395
|
+
drifts.append({"path": path, "error": "missing"})
|
|
1396
|
+
elif open(path, "rb").read() != data:
|
|
1397
|
+
drifts.append({"path": path, "error": "bytes_differ"})
|
|
1398
|
+
if drifts:
|
|
1399
|
+
for d in drifts:
|
|
1400
|
+
print("DRIFT:", d)
|
|
1401
|
+
sys.exit(1)
|
|
1402
|
+
print(f"[seed_b6b_frontend] verify ok: {len(built['assets'])} seeds + "
|
|
1403
|
+
f"{len(built['entry_bytes'])} policies(字节逐等)")
|
|
1404
|
+
return
|
|
1405
|
+
|
|
1406
|
+
changed = 0
|
|
1407
|
+
for path, data in sorted(outputs.items()):
|
|
1408
|
+
if write_if_changed(path, data):
|
|
1409
|
+
changed += 1
|
|
1410
|
+
print("WROTE:", os.path.relpath(path, VNEXT))
|
|
1411
|
+
print(f"[seed_b6b_frontend] ok: {len(outputs)} outputs({changed} changed / "
|
|
1412
|
+
f"{len(outputs) - changed} unchanged);seeds={len(built['assets'])} "
|
|
1413
|
+
f"policies={len(built['entry_bytes'])} "
|
|
1414
|
+
f"(required={built['counts']['required']}, advisory={built['counts']['advisory']})")
|
|
1415
|
+
print("LCS audits max:", max(a["lcs_max"] for a in built["audits"]))
|
|
1416
|
+
if built["excluded"]:
|
|
1417
|
+
print("保守排除留池待复核:")
|
|
1418
|
+
for e in built["excluded"]:
|
|
1419
|
+
print(f" - [{e['pool']}] {e['candidate_id']}: {e['reason']}")
|
|
1420
|
+
print("下一步:corepack pnpm pomaster catalog relock(168→193)")
|
|
1421
|
+
|
|
1422
|
+
|
|
1423
|
+
if __name__ == "__main__":
|
|
1424
|
+
main()
|